Хотя этот вопрос можно считать слишком широким и поэтому не по теме, он хорошо написан и описывает проблему, с которой сталкиваются многие неопытные разработчики - поэтому я думаю, что он заслуживает ответа.
Итак, давайте разберем его по составляющим:
Q: Как вернуть значение столбца identity
после вставки?
A: SQL Server предоставляет несколько способов сделать это, самый простой из них, вероятно, будет scope_identity
, но лучшим будет использование предложения output
.
Q: Как отправить несколько строк в хранимую процедуру?
A: Использовать табличный параметр .
Теперь посмотрим, как именно мы это сделаем.
Первое, что нам нужно сделать, это создать пользовательский тип таблицы, который будет использоваться для параметра с табличным значением - так:
CREATE TYPE [dbo].[Udt_OrderItems] AS TABLE
(
productId int NOT NULL,
productQuantity int,
);
GO
Затем мы можем создать хранимую процедуру, используя этот тип в качестве параметра с табличным значением.
Мы также отправим детали заказа в виде скалярных параметров в хранимую процедуру:
CREATE PROCEDURE stp_InsertOrderWithItems
(
@customerName varchar(30),
@customerAddress varchar(30),
@submitDate date,
@realizationDate date,
@deliveryTypeId int,
@orderItems dbo.Udt_OrderItems readonly -- Table valued parameters must be readonly
)
AS
DECLARE @Ids AS TABLE (orderId int NOT NULL) -- for the output clause
INSERT INTO dbo.Orders (customerName, customerAddress, submitDate, realizationDate, deliveryTypeId)
OUTPUT inserted.Id INTO @Ids
VALUES(@customerName, @customerAddress, @submitDate, @realizationDate, @deliveryTypeId)
INSERT INTO dbo.OrderItems (orderId, productId, productQuantity)
SELECT orderId, productId, productQuantity
FROM @orderItems
CROSS JOIN @Ids -- We only have one value in @Ids so cross join is safe
GO
Что касается части c #, это зависит от того, как вы подключаетесь к базе данных - я покажу пример базовой версии ADO.Net:
using(var con = new SqlConnection(connectionString))
{
using(var cmd = new SqlCommand(con, "stp_InsertOrderWithItems"))
{
var dt = new DataTable()
dt.Columns.Add("productId", typeof(int));
dt.Columns.Add("productQuantity", typeof(int));
// populate data table here
cmd.Parameters.Add("@customerName", SqlDbType.VarChar, 30).Value = customerName;
// all the other scalar parameters here...
cmd.Parameters.Add(@orderItems, SqlDbType.Structured).Value = dt;
con.Open();
cmd.ExecuteNonQuery();
}
}