我有一个现有表A
,定义如下:
CREATE TABLE dbo.A(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
name nvarchar(255) NOT NULL UNIQUE NONCLUSTERED
);
该表有 1,000 条现有记录。
我现在需要一个新表 B
,定义如下:
CREATE TABLE dbo.B(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
some_value int NOT NULL
);
我需要在 B
中为 A
中的每条记录创建一条记录,并将 A
记录中的引用添加到相应的 >B
记录。首先,我需要向表 A
添加一个引用表 B
的新字段(该字段必须可以为空,默认值为 NULL
,在此阶段):
ALTER TABLE dbo.A
ADD b_id int NULL references dbo.B;
如何创建必要的 B
记录并相应地更新 A.b_id
字段?我正在寻找这样的东西:
UPDATE dbo.A
SET b_id = (INSERT INTO dbo.B(some_value) VALUES(5));
这样b_id
的值就是新插入的B
的id
字段。 (显然,此查询无效。)
我能想到的唯一解决方案是使用多个单独的查询编写复杂的存储过程。有没有办法通过单个查询来完成此操作?
最佳答案
IF我理解正确,这里不需要CURSOR
。您可以做的是MERGE
,它允许您OUTPUT
来自源数据和目标的两列:
CREATE TABLE dbo.A(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
name nvarchar(255) NOT NULL UNIQUE NONCLUSTERED
);
GO
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N))
INSERT INTO dbo.A
SELECT NEWID()
FROM N N1, N N2, N N3;
GO
CREATE TABLE dbo.B(
id int IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
some_value int NOT NULL
);
GO
ALTER TABLE dbo.A
ADD b_id int NULL references dbo.B;
GO
DECLARE @IDs table (a_id int, b_id int)
MERGE dbo.B B
USING dbo.A A ON B.id = A.b_id
WHEN NOT MATCHED BY TARGET THEN
INSERT (some_value)
VALUES(RAND() * 1000)
OUTPUT A.id, inserted.id
INTO @IDs;
UPDATE A
SET b_id = I.b_id
FROM dbo.A A
JOIN @Ids I ON A.id = I.a_id;
GO
SELECT *
FROM dbo.A;
GO
DROP TABLE dbo.A;
DROP TABLE dbo.B;
关于sql-server - 使用 INSERT 查询的结果更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68071585/