如何在没有光标的情况下进行多次插入

时间:2009-09-03 21:06:21

标签: sql sql-server tsql

假设我有两张桌子

tblA(    tableAID INT IDENTITY(1,1),    foo VARCHAR(100))

tblB(    tableBID INTIDENTITY(1,1),    tableAID INT,    bar varchar(100))

tblB.tableAID是一个FK到tblA。

我想在这对表中插入一堆记录(从系统中的其他表中提取)。在插入tblB之前,我需要知道插入到tblA中的ID是什么。

有没有办法在不逐行处理的情况下执行此操作?

4 个答案:

答案 0 :(得分:3)

在SQL Server 2005及更高版本中,您可以使用OUTPUT子句将新键值传递到第二个表中:

INSERT INTO T ...
OUTPUT PrimaryKeycol, otherValues INTO ChildTable;

SQL Server 2008中存在“可组合DML”和MERGE语句的其他可能性。

在回复评论时添加:

create table T(i int identity(1,1), j int, k int default -1);
go

merge into T using (values (1), (2)) as U(j)
on U.j = T.j
when not matched then insert (j) values (j)
output inserted.i, inserted.k;
go

drop table T;

答案 1 :(得分:0)

你能使用临时表吗?

DECLARE @t TABLE (foo, int, ba VARCHAR(50))
INSERT INTO @t (foo, bar) SELECT foo, bar FROM your_other_table
ALTER TABLE @t ADD id_a INT IDENTITY(1, 1)

您应该使用SET IDENTITY_INSERT OFF来执行此操作

也许你希望reseed你的桌子在桌子投入生产时进行适当的插入。

DBCC CHECKIDENT 'tblA' RESEED, newValue

答案 2 :(得分:0)

假设您真正问的是如何避免多次往返服务器,那么一种方法是编写一个存储过程,同时执行两次插入,并使用

Set @Pk = Scope_Identity() 

在第一次插入之后获取为第一个插入创建的Identity值,然后将该@Pk值用于第二个插入。

这是一个简单的例子

Create Procedure SaveEmployee
@Name varChar(30),
@DivId Int,
@HomePhoneNumber VarChar(12),
@FaxNumber VarChar(12)
As
Set NoCount On
Declare @Pk Integer


   Insert Employees(Name, Divisionid)
   Values(@Name, @DivId)
   Set @Pk = Scope_Identity()
   -- ------------------------------------------------
   Insert PhoneNums(EmployeeId, PhoneType, PhoneNumber)
   Values(@Pk, 'Home', @HomePhoneNumber)
   -- ------------------------------------------------
   Insert PhoneNums(EmployeeId, PhoneType, PhoneNumber)
   Values(@Pk, 'Fax', @FaxNumber )

   Return 1

答案 3 :(得分:0)

它可能超过它有用的地步,但这指出了使用代理主键的固有困难,特别是在其他表中使用它们作为外键时。如果您的关系是使用自然键定义的,那么您从一开始就知道要插入什么值。