为什么 table 被外键更新为 NULL?
Why is table being updated with NULL for foreign key?
我有一个名为 Paychecks
的 table,它包含 294 行。我创建了一个名为 TaxableEmployerPaidItems
的新 table。它的主键是 Paychecks
.
的外键
我正在遍历 Paychecks
并为 Paychecks
中的每一行在 TaxableEmployerPaidItems
中插入一行,然后更新外键。 294 行被插入到 TaxableEmployerPaidItems
中,如我所料。
在Paychecks
中,前114行包含指向TaxableEmployerPaidItems
的外键,然后在第114行之后所有外键都是NULL。
为什么会这样?
这是我的存储过程中的代码:
BEGIN
SET NOCOUNT ON;
DECLARE @RowCnt INT
DECLARE @TaxableEmployerPaidItemsIDInserted INT
SET @RowCnt = (SELECT COUNT(PaycheckID) FROM [dbo].[Paychecks])
DECLARE @I INT
SET @I = 1
-- LOOP through rows of dbo.Paychecks
WHILE (@I <= @RowCnt)
BEGIN
INSERT INTO [dbo].[TaxableEmployerPaidItems]
(Item1Amount, Item1Description, Item2Amount, Item2Description, Item3Amount, Item3Description, Deleted)
VALUES (NULL, NULL, NULL, NULL, NULL, NULL, 0)
UPDATE [dbo].[Paychecks]
SET TaxableEmployerPaidItemsId = @@IDENTITY
WHERE PaycheckID = @I
SET @I = @I + 1
END
END
您的问题无法重现(请参阅此 DBFiddle). However you don't want to be doing this sort of thing in a loop. SQL is a set based language so you should therefore be attempting to solve your problem in a set based manner before reverting to a loop. In this case you just need to make use of the MERGE
statement and the OUTPUT
clause。
create table #NewId (id int, OtherId int);
merge dbo.PaidItems with (holdlock) as Target
using dbo.Paychecks as Source
on 1 = 0 -- force insert
when not matched by Target
then insert (Item1Amount, Item1Description, Item2Amount, Item2Description, Item3Amount, Item3Description, Deleted)
values (NULL,NULL,NULL,NULL,NULL,NULL,0)
output Inserted.PaidItemID, Source.PaycheckID into #NewId (id, OtherId);
update P set
TaxableEmployerPaidItemsId = N.id
from dbo.Paychecks P
inner join #NewId N on N.OtherId = P.PaycheckID;
drop table #NewId;
您需要 MERGE
而不是 INSERT
的原因是因为只有在 MERGE
中您才能访问 [=12] 中的源 table 列=] 子句。
注意:如果您发现自己在某些时候需要使用 @@IDENTITY
,那么在大多数情况下,使用 SCOPE_IDENTITY()
.
会更安全
有关 MERGE
的更多信息,包括为什么要使用锁定提示 WITH (HOLDLOCK)
。
我有一个名为 Paychecks
的 table,它包含 294 行。我创建了一个名为 TaxableEmployerPaidItems
的新 table。它的主键是 Paychecks
.
我正在遍历 Paychecks
并为 Paychecks
中的每一行在 TaxableEmployerPaidItems
中插入一行,然后更新外键。 294 行被插入到 TaxableEmployerPaidItems
中,如我所料。
在Paychecks
中,前114行包含指向TaxableEmployerPaidItems
的外键,然后在第114行之后所有外键都是NULL。
为什么会这样?
这是我的存储过程中的代码:
BEGIN
SET NOCOUNT ON;
DECLARE @RowCnt INT
DECLARE @TaxableEmployerPaidItemsIDInserted INT
SET @RowCnt = (SELECT COUNT(PaycheckID) FROM [dbo].[Paychecks])
DECLARE @I INT
SET @I = 1
-- LOOP through rows of dbo.Paychecks
WHILE (@I <= @RowCnt)
BEGIN
INSERT INTO [dbo].[TaxableEmployerPaidItems]
(Item1Amount, Item1Description, Item2Amount, Item2Description, Item3Amount, Item3Description, Deleted)
VALUES (NULL, NULL, NULL, NULL, NULL, NULL, 0)
UPDATE [dbo].[Paychecks]
SET TaxableEmployerPaidItemsId = @@IDENTITY
WHERE PaycheckID = @I
SET @I = @I + 1
END
END
您的问题无法重现(请参阅此 DBFiddle). However you don't want to be doing this sort of thing in a loop. SQL is a set based language so you should therefore be attempting to solve your problem in a set based manner before reverting to a loop. In this case you just need to make use of the MERGE
statement and the OUTPUT
clause。
create table #NewId (id int, OtherId int);
merge dbo.PaidItems with (holdlock) as Target
using dbo.Paychecks as Source
on 1 = 0 -- force insert
when not matched by Target
then insert (Item1Amount, Item1Description, Item2Amount, Item2Description, Item3Amount, Item3Description, Deleted)
values (NULL,NULL,NULL,NULL,NULL,NULL,0)
output Inserted.PaidItemID, Source.PaycheckID into #NewId (id, OtherId);
update P set
TaxableEmployerPaidItemsId = N.id
from dbo.Paychecks P
inner join #NewId N on N.OtherId = P.PaycheckID;
drop table #NewId;
您需要 MERGE
而不是 INSERT
的原因是因为只有在 MERGE
中您才能访问 [=12] 中的源 table 列=] 子句。
注意:如果您发现自己在某些时候需要使用 @@IDENTITY
,那么在大多数情况下,使用 SCOPE_IDENTITY()
.
有关 MERGE
的更多信息,包括为什么要使用锁定提示 WITH (HOLDLOCK)
。