为什么 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)