在我的应用程序中,我有大量(100+)行需要插入到数据库中。一旦他们被插入数据库,我需要插入他们的孩子,这些孩子有一个外键引用回孩子。
我想知道是否有一种方法可以编写一个可以插入所有这些行并将它们的 ID 返回给我的应用程序的存储过程?
在我的应用程序中,我有大量(100+)行需要插入到数据库中。一旦他们被插入数据库,我需要插入他们的孩子,这些孩子有一个外键引用回孩子。
我想知道是否有一种方法可以编写一个可以插入所有这些行并将它们的 ID 返回给我的应用程序的存储过程?
您已使用 table-value-parameters 标记了您的问题 - 您可以将其中一个传递给存储过程以插入数据库。
您可以使用OUTPUT
带有逻辑表的子句INSERTED
来获取新的 ID 值并从存储过程中返回这些值。
这是使用该子句的示例output
,就像 Oded 建议的那样。首先,一些设置代码:
if exists (select * from tempdb.sys.tables where name like '#tmp%')
drop table #tmp
create table #tmp (id int identity, FirstName varchar(50), LastName varchar(50))
if exists (select * from sys.procedures where name = 'TestProcedure')
drop procedure TestProcedure
if exists (select * from sys.types where name = 'TestTableType')
drop type TestTableType
create type TestTableType as table (FirstName varchar(50), LastName varchar(50))
go
现在我们可以创建存储过程:
create procedure dbo.TestProcedure
@List TestTableType readonly
as
insert #tmp
(FirstName, LastName)
output inserted.*
select FirstName
, LastName
from @List l
go
请注意该output
子句,它告诉 SQL Server 将插入的行返回给客户端,包括标识列的值。现在代码都设置好了,我们可以测试它:
declare @List TestTableType
insert @List values ('Rick','Cain'),
('Herman', 'Gingrich'),
('Newt', 'Paul'),
('Ron', 'Perry')
exec dbo.TestProcedure @List
select * from #tmp
您会看到该过程返回的值与这些值#tmp
完全匹配。
我会做类似于 Andomar 建议的事情,但使用此处描述的“INSERT-EXEC”技术:
http://www.sommarskog.se/tableparam.html
在链接中,搜索:INSERT-EXEC
我仍在研究如何执行此操作,但在我看来,如果您想插入父表和子表,可以通过将两个表作为表值参数传入一个 sql 调用来完成。如果您有一些人为的身份(关系),它当前像行号一样链接两个表,但不一定存储在任一 DB 表中,那么当插入父级并获取其身份值时,它可以连接到子表使用唯一关系和孩子的外键可以更新。然后可以插入孩子。
输出很有趣,但我实际上并不需要输出,它只需要在存储过程中使用,所以我必须做更多的研究来看看输出是否可以使用,例如,将它输出到临时桌子。
回答我自己的问题,输出的语法是:
[ OUTPUT <dml_select_list> INTO { @table_variable | output_table } [ ( column_list ) ] ]
所以它可以用来创建一个与孩子连接的临时表。