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
编辑 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