No SQL Server 2008+, há maneiras mais fáceis de inserir várias linhas em uma única instrução. Por exemplo, esta sintaxe é válida:
INSERT dbo.table(col1, col2) VALUES
(1, 2),
(2, 3),
(3, 4);
O acima irá inserir três linhas. Em versões mais antigas, você pode fazer coisas um pouco mais detalhadas, como:
INSERT dbo.table(col1, col2)
SELECT 1, 2
UNION ALL SELECT 2, 3
UNION ALL SELECT 3, 4;
Claro que seu
ExecuteNonQuery
não precisa ser um único comando, você pode passar isso como uma única string e ainda funcionará:INSERT dbo.table(col1, col2) VALUES(1, 2);
INSERT dbo.table(col1, col2) VALUES(2, 3);
INSERT dbo.table(col1, col2) VALUES(3, 4);
Se você quiser fazer isso em um procedimento armazenado, poderá realizar facilmente uma divisão em parâmetros de vários valores, por exemplo, se passar a seguinte string:
1,2;2,3;3,4
Você pode processar esses valores usando uma função como a que postei aqui:
Divida os pares de valores e uma tabela de criação usando UDF
Então seu procedimento pode ficar assim:
CREATE PROCEDURE dbo.AddOrderLineItems
@LineItems VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.OrderItems(Product, Quantity)
SELECT Product, Quantity FROM dbo.MultiSplit(@LineItems);
END
GO
E você o chamaria usando o equivalente em C# de:
EXEC dbo.AddOrderLineItems @LineItems = '1,2;2,3;3,4';
Ou você pode usar parâmetros com valor de tabela, conforme sugerido por Alexey. Um exemplo rápido:
CREATE TYPE OrderLineItem AS TABLE
(
Product INT,
Quantity INT
);
Então você pode criar um procedimento:
CREATE PROCEDURE dbo.AddOrderLineItems
@LineItems OrderLineItem READONLY
-- other parameters
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.OrderItems(Product, Quantity)
SELECT Product, Quantity FROM @LineItems;
END
GO
Em seguida, crie o TVP equivalente em seu código C# (não sou o cara que você quer fazer isso; você pode ver um exemplo aqui ).
No entanto, existem algumas ressalvas, por favor, veja esta pergunta:
Criando um parâmetro generalizado type para uso como parâmetro de valor de tabela