作者:报告大王报报报报告大王 | 来源:互联网 | 2022-11-30 11:04
1> Zohar Peled..:
虽然这个问题可能被认为过于宽泛而且非常偏离主题,但它写得很好并描述了许多缺乏经验的开发人员所面临的问题 - 所以我认为它应该得到答案.
所以让我们把它分解成它的成分:
问:如何identity
在插入后获取列的值?
答: SQL Server提供了几种方法,最简单的可能是scope_identity
,但最好的方法是使用该output
子句.
问:如何将多行发送到存储过程?
答:使用表值参数.
现在让我们看看我们究竟要做到这一点.
我们需要做的第一件事是创建一个用户定义的表类型,用于表值参数 - 所以:
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();
}
}