假设我有两张桌子
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是什么。
有没有办法在不逐行处理的情况下执行此操作?
答案 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)
它可能超过它有用的地步,但这指出了使用代理主键的固有困难,特别是在其他表中使用它们作为外键时。如果您的关系是使用自然键定义的,那么您从一开始就知道要插入什么值。