Entonces puedes hacerlo del modo que te expuse en el link, creas un tipo de dato tabla
CREATE TYPE [dbo].[testParam] AS TABLE( [id] [int] NOT NULL, [val1] [varchar](50) NULL, [val2] [varchar](50) NULL, PRIMARY KEY CLUSTERED ( [id] ASC )WITH (IGNORE_DUP_KEY = OFF) ) GO
CREATE TABLE [dbo].[testing]( [id] [int] NOT NULL, [val1] [varchar](50) NOT NULL, [var2] [varchar](50) NOT NULL, CONSTRAINT [PK_testing] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
Creas el procedure que recibe el lote en una tabla
create procedure test @param testParam readonly as insert into dbo.testing select * from @param;
Y lo invocas asi desde el SSMS
declare @par testParam insert into @par VALUES (1, 'Manuela','Vera') insert into @par VALUES (2, 'Josefa','Medina') insert into @par VALUES (3, 'Pablo','Garmendia') execute dbo.test @param = @par select * from dbo.testing
y si necesitas de una aplicacion en .net
try { var dataTable = new DataTable(); dataTable.Columns.Add("Id", typeof(int)); dataTable.Columns.Add("val1", typeof(string)); dataTable.Columns.Add("val2", typeof(string)); dataTable.Rows.Add(1, "Jose", "Rodriguez"); dataTable.Rows.Add(2, "María", "Benitez"); dataTable.Rows.Add(3, "Marcela", "Troche"); using (var conn = new SqlConnection("Server=10.10.10.1;Initial Catalog=devtroce;user ID=devtroce;password=*********")) { using (var cmd = new SqlCommand("test", conn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@param", dataTable); conn.Open(); cmd.ExecuteNonQuery(); MessageBox.Show("guardado con éxito"); } } } catch(Exception ex) { MessageBox.Show(ex.Message); }