我有2个具有外键约束的表:
Table A:
[id] int identity(1, 1) PK,
[b_id] INT
和
Table B:
[id] int identity(1, 1) PK
其中[b_id]指的是表B的[id]列。
任务是: 每次插入表A,并将新记录放入表B并更新[b_id]。
使用Sql Server 2008 r2。
感谢任何帮助。
答案 0 :(得分:1)
第一次误解了这个,我发布了一个完全不同的答案。
首先,如果表B是父表,则首先插入其中。然后你获取id值并插入表A。
最好这样做是一次交易。根据其他字段的不同,您可以使用表B中的触发器填充表A,或者您可能需要编写直接的SQL代码或存储过程来完成工作。
如果您有两个表的表模式,将更容易描述要执行的操作。但是,假设表B只有一列而表A只有ID和B_id,这就是代码可以工作的方式(您可能希望为生产代码添加显式事务)。该示例用于单个记录插入,这不会从触发器发生。触发器应始终处理多个记录插入,然后必须以不同方式编写。但是,如果不知道表中的列是什么,很难提供一个很好的例子。
create table #temp (id int identity)
create table #temp2 (Id int identity, b_id int)
declare @b_id int
insert into #temp default values
select @B_id = scope_identity()
insert into #temp2 (B_id)
values(@B_id)
select * from #temp2
如果有其他列,问题会变得更复杂,因为你也必须为它们提供值。
答案 1 :(得分:0)
如果不删除标识规范,您可以使用以下选项: SET IDENTITY_INSERT B ON
试试这个:
CREATE TRIGGER trgAfterInsert ON [dbo].[A]
FOR INSERT
AS
IF @@ROWCOUNT = 0 RETURN;
SET NOCOUNT ON;
SET IDENTITY_INSERT B ON
DECLARE @B_Id INT
SELECT @B_Id = ISNULL(MAX(Id), 0) FROM B;
WITH RES (ID, BIDS)
AS
(SELECT Id, @B_Id + ROW_NUMBER() OVER (ORDER BY Id) FROM INSERTED)
UPDATE A SET [b_Id] = BIDS
FROM A
INNER JOIN RES ON A.ID = RES.ID
INSERT INTO B (Id)
SELECT @B_Id + ROW_NUMBER() OVER (ORDER BY Id) FROM INSERTED
SET IDENTITY_INSERT B OFF
GO
答案 2 :(得分:-1)
虽然Nadeem的回答是正确的,但由于某种原因,他的触发器需要max.id而不是NEW.id,并且不会相应地更新A.
对于你要求触发器可用的内容,你需要表A中的FK是可以为空的,否则表之间会有竞争条件。
编辑:正如SpectralGhost指出的那样,我的原始代码不支持多行,这一行会做:CREATE TRIGGER trgAfterInsertA ON TableA
FOR INSERT
AS
DECLARE db_cursor CURSOR FOR
SELECT id FROM INSERTED
DECLARE @an_id int
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @an_id
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TableB VALUES(VALUE_PLACEHOLDER)
UPDATE TableA
SET b_id = SCOPE_IDENTITY()
WHERE id = @an_id
FETCH NEXT FROM db_cursor INTO @an_id
END
GO
VALUE_PLACEHOLDER是使用。初始化TableB的值。