【问题标题】:Insert row using a SELECT, and update the source table row with the target new row Id使用 SELECT 插入行,并使用目标新行 ID 更新源表行
【发布时间】:2021-08-12 08:26:06
【问题描述】:

我有一个表 SourceTable,我想将它的一些数据复制到 TargetTable 中。 TargetTable 是具有现有行和标识 id 的现有表。

在 SourceTable 上,有一列是 TargetTable 的外键,例如源表.TargetTableId

我需要做的是将 SourceTable 中的行插入 TargetTable,然后使用 TargetTable 中新创建的 Id 更新 SourceTable.TargetTableId。

由于行不够唯一,我无法通过匹配多列进行插入和后续更新。

插入需要“插入新表并更新现有表的列,该列是新表的外键,具有新行的id”。

CREATE TABLE #SourceTable
(
    Id INT IDENTITY(1,1),
    Field1 NVARCHAR(MAX),
    Field2 NVARCHAR(MAX),
    TargetTableId INT
)

CREATE TABLE #TargetTable
(
    Id INT IDENTITY(245,1),
    Field1 NVARCHAR(MAX),
    Field2 NVARCHAR(MAX),
)

INSERT INTO #SourceTable(Field1, Field2)
VALUES
('Apple','Pie'),
('Chocolate','Cake'),
('Apple','Pie')

INSERT INTO #TargetTable(Field1, Field2)
SELECT Field1, Field2
FROM #SourceTable

SourceTable 上的期望结果:

Id - Field1 - Field2 - TargetTableId
1 - Apple - Pie - 245
2 - Chocolate - Cake - 246
3 - Apple - Pie - 247

【问题讨论】:

  • INSERT 和 `OUTPUT` 到另一个表中,然后你有新的 ID?上面的真的很模糊。示例数据、预期结果 您的尝试将帮助我们帮助您。
  • 听起来您应该考虑使用 AFTER INSERT 触发器,然后将 @@IDENTITY 添加到 SourceTable 中。
  • 考虑到 OP 说“行”@SchmitzIT,我怀疑 @@IDENTITY(或更好的 SCOPE_IDENTITY)将提供 OP 想要的值。
  • @Larnu。使用示例数据和预期结果发布更新。非常感谢。
  • Wjere 是 245、246 和 247 来自哪里?

标签: sql sql-server tsql


【解决方案1】:

似乎您需要使用旧的MERGE 方法来处理来自源数据和目标的OUTPUT 值。然后您可以将该数据放入表变量/临时表中并使用它来执行您的UPDATE

MERGE #TargetTable TT
USING #SourceTable ST ON ST.TargetTableId = TT.ID
WHEN NOT MATCHED THEN
    INSERT (Field1,Field2)
    VALUES(ST.Field1, ST.Field2)
OUTPUT ST.ID, inserted.ID INTO @IDs;

UPDATE ST
SET TargetTableId = I.TargetID
FROM #SourceTable ST
     JOIN @IDs I ON ST.Id = I.SourceID;
GO

SELECT *
FROM #SourceTable;

【讨论】:

  • 完美!谢谢
【解决方案2】:

你可以根据需要做这样的事情。

  • 只需创建临时表 #TargetTableForInsert
  • 将此数据也插入到此表中,并添加 ID 为 SourceTable
  • 最后根据 TargetTableForInsert 更新您的主表

你来了:)

CREATE TABLE #SourceTable
(
    Id INT IDENTITY(1,1),
    Field1 NVARCHAR(MAX),
    Field2 NVARCHAR(MAX),
    TargetTableId INT
)

CREATE TABLE #TargetTable
(
    Id INT IDENTITY(245,1),
    Field1 NVARCHAR(MAX),
    Field2 NVARCHAR(MAX)
)


CREATE TABLE #TargetTableForInsert
(
    Id INT IDENTITY(245,1),
    Field1 NVARCHAR(MAX),
    Field2 NVARCHAR(MAX),
    SourceTableId INT
)


INSERT INTO #SourceTable(Field1, Field2)
VALUES
('Apple','Pie'),
('Chocolate','Cake'),
('Apple','Pie')

INSERT INTO #TargetTable(Field1, Field2)
SELECT Field1, Field2 
FROM #SourceTable

INSERT INTO #TargetTableForInsert(Field1, Field2, SourceTableId)
SELECT Field1, Field2 ,Id
FROM #SourceTable


update #SourceTable
set TargetTableId =  ST.Id
FROM #SourceTable ST
     join #TargetTableForInsert TG on ST.id = TG.SourceTableId





select 'SourceTable',* from #SourceTable

select 'SourceTable',* from #TargetTable

【讨论】:

  • 感谢 Adamszsz。同意这适用于我在原始帖子中的示例。非常感谢,但是,在我真正想做的事情中,我没有使用新创建的临时表——它们是现有的表,我不想在“TargetTable.”中添加一个新列。
  • 已编辑,现在按您的意愿检查 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 2014-01-15
相关资源
最近更新 更多