Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como inserir várias linhas no SQL usando procedimentos armazenados?


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