SQL 服务器 - 变量停止在循环内赋值

SQL Server - variable stops being assigned inside a loop

编辑 2:

我添加了本示例中使用的 table 结构,以尝试阐明问题。感谢@Sean 的推荐和耐心等待。

Create Table TheHeaderTable(
    id       bigint Identity(1,1)   not null,
    varOne   datetime,
    varTwo   nvarchar(30),
    varThree nvarchar(30),
    varFour  nvarchar(6)

    constraint PK_TheTable primary key (id)
)

Create Table TheDetailsTable(
    FK_Bitacora_id bigint, --FK to TheTable.id
    isPK    bit,
    nuevo   varchar(10),
    viejo   varchar(10)

    constraint FK_TheDetailsTable foreign key (FK_Bitacora_id) references TheTable(id)
)

我还将 table 名称从 "TheTable" 更改为 "TheHeaderTable" 以便说明。

原版Post

SQL 服务器 2012

嗨,我在尝试从另一个数据库(在另一个数据库中,同一实例)向一个 table 进行批量插入时遇到问题。

我基本上在同一台服务器上有2个结构相同的数据库,我需要从2个数据库table中插入信息(一个是"header",另一个是详情)。

header 有一个自动递增的 Identity,而且数据库已经被使用,所以我不能简单地将所有数据从一个复制到另一个,必须刷新 ID。我附带了以下代码(更改了 table 和变量名称)

declare @id     bigInt   --PK
declare @varOne datetime
declare @varTwo nvarchar(30)
declare @varThree   nvarchar(30)
declare @varFour    nvarchar(6)

declare @outTable table (id bigint)
declare @outId bigint

declare db_cursor CURSOR FOR  
SELECT *
FROM AnotherDatabase.dbo.TheHeaderTable

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @id, @varOne, 
@varTwo, @varThree, @varFour

WHILE @@FETCH_STATUS = 0   
BEGIN   
    Insert into TheHeaderTable
    (varOne, varTwo, varThree, varFour)
    Output Inserted.id into @outTable
    VALUES
    (@varOne, @varTwo, @varThree, @varFour)

    select @outId = id from @outTable

    Insert into TheDetailsTable
    (FK_Bitacora_id, nombre, isPK, nuevo, viejo)
    select @outID, nombre, isPK, nuevo, viejo
    from AnotherDatabase.dbo.TheDetailsTable
    where FK_Bitacora_id = @id

    FETCH NEXT FROM db_cursor INTO @id, @varOne, 
        @varTwo, @varThree, @varFour
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

该代码起初似乎有效,几千行后 "Details Table" 为空。经过一番调查后,我决定查看出现此问题的第一个实例,然后我从 ID 中减去 1,然后我发现了一些非常奇怪的事情:所有详细信息(从那时起)都被插入到该特定 ID

我做了一个查询来计算脚本的插入次数(忽略所有可能从外部源新插入的内容)和这个问题之前的循环次数是:115967

@outTable 或@outIs 似乎未正确更新。但老实说,我不知道为什么会这样。

如果能得到任何帮助,我将不胜感激。

谢谢!

编辑 1:

澄清一下:

TheHeaderTable”中的主键是“id”。 “TheDetailsTable”通过外键“FK_Bitacora_id”与 headertable 链接(引用 id ).

TheHeaderTable 中的 ID 是自动生成的,这就是我在插入时捕获其值的原因,但要插入详细信息,我需要找到所有行(在 TheDetailsTable) 与其原始 ID 相匹配。

伙计,我希望我是在清理事情,而不是相反。

由于您需要捕获新插入的标识,因此您可以像以前一样使用 OUTPUT。但是你不需要在这里循环。只需插入,然后加入您的另一个 table。您发布的所有代码都可以简化为这个基于集合的逻辑。考虑到行数,我建议使用临时 table 而不是 table 变量,这样您就可以添加聚簇索引。

create table #outTable
(
    id bigint primary key clustered
)

Insert into TheTable
(
    varOne
    , varTwo
    , varThree
    , varFour
)
Output Inserted.id into #outTable
select varOne
    , varTwo
    , varThree
    , varFour
from AnotherDatabase.dbo.TheHeaderTable

Insert into TheDetailsTable
(
    FK_Bitacora_id
    , nombre
    , isPK
    , nuevo
    , viejo
)
select ot.id
    , nombre
    , isPK
    , nuevo
    , viejo
from AnotherDatabase.dbo.TheDetailsTable d
join #outTable ot on ot.id = d.FK_Bitacora_id

drop table #outTable