【发布时间】:2011-11-21 23:32:45
【问题描述】:
我“继承了”一段出色的 TSQL 代码可以做到这一点:
- 在游标上逐行循环。
- 游标包含表A中需要合并(Upserted)的数据
- 对于游标中的每个行循环,都会调用一个存储过程。过程:
- 如果表 A 中存在相应的行,则更新该行
- 如果这样的行不存在,则:
- 在不同的表 B 中插入一行。
- 获取新生成的 ID(比如它称为 IDB)
- 在表 A 中插入单行。表 A 插入 需要一个 IDB(该字段不为空,它应该只有表 B 中的值,但没有 FK 约束)
显然这很糟糕(性能和优雅的原因)!!
问题 起初,这看起来像是 MERGE 使用的标准案例。我试着做:
MERGE [dbo].[TableA] AS Target
USING <cursor data set as a select statement> as Src on target.IDA = Src.IDA
WHEN MATCHED
//update
WHEN NOT MATCHED
//insert <------ Fails because obviously a new IDB is required
还尝试了各种方法,例如 nested select that sends IDB on the OUTPUT,但由于 IDB 是 PK 导致失败。
其他类型的合并也失败了,例如:
MERGE Table A with <cursor data set as a select statement>
...
MERGE Table A with Table B
WHEN NOT MATCHED
//insert on Table A
WHEN NOT MATCHED
// Update Table B
有人对此有想法吗?从本质上讲,我认为如果我们将问题概括为:
Can I insert and return the PK in one statement that can be nested in other statements
提前感谢您的任何回复
乔治
【问题讨论】:
-
你可以合并到tableB并使用technique here我认为。
-
谢谢,看到了。它实际上是一个好主意。本质上,这家伙将新生成的 Id 存储在临时变量中。与我正在寻找的不同(在 1 Merge 中完成整个过程),但它仍然是一种有趣的方法。谢谢马丁。
-
+1 用于使用“upserted”这个词...:)
-
什么是 IDB?是否可以将该 IDB 更改为自动增量或某种默认值?此外,您能否将生成新 ID 的行为封装到一个函数中,然后在您的合并语句中使用它?
标签: sql-server tsql sql-server-2008 merge upsert