【问题标题】:cascading copy with merge statement causing lock issues使用合并语句的级联副本导致锁定问题
【发布时间】:2023-03-07 20:56:01
【问题描述】:
SQL Server 2012 (SP1) with 64GB ram using 50GB for max server memory
sp_configure 'locks' = 0
trace flags 1211 & 1224 are off
using READ_COMMITTED
SET LOCK_TIMEOUT 0

使用MERGE 时出现此错误:

SQL Server 数据库引擎的实例此时无法获取 LOCK 资源。当活动用户较少时重新运行您的语句。请数据库管理员检查此实例的锁和内存配置,或检查长时间运行的事务。

太多的开发人员在合并方面遇到了持续的问题,那么我们如何才能有效地对父/子表的行和相关行进行级联复制。例如。 tableA 有很多 tableB 行,tableC 有很多 tableD 行等...

MERGE 在创建新标识值时很有用,而在同一行上保留旧标识以查看下一个表插入的数据,是否有替代方案?

使用单表插入OUTPUT命令,不能同时获取新旧ID

INSERT INTO tableA
OUTPUT  inserted.[ID],inserted.[col1],inserted.[col2],inserted.col3,
INTO #tmptable

在 SQL Server 中执行此操作的最佳选项是什么?

【问题讨论】:

  • 序列化隔离级别有帮助吗?
  • 已经使用 READ COMMITTED 并没有帮助,在网上搜索使用 MERGE 有太多问题,使用事务变得更加丑陋,解决使用我发现的一个整洁的 hack:tableA 创建一个 sourceID 字段,然后执行:INSERT INTO tableA(col1,col2,col3,sourceID) OUTPUT inserted.[col1],inserted.[col2],inserted.col3,inserted.[currentID] INTO #tmptable SELECT col1,col2,col3,currentID as源ID。通过这种方式,您可以在 INSERT 完成后在同一行获取新 ID 和旧 ID,希望这对其他人有所帮助。
  • 使用查询提示,例如MERGE 的强制搜索和过滤 cte 或查看目标也没有帮助 - stackoverflow.com/questions/7407560/…
  • 如果不坐下来解决问题,我不知道如何写这个。你可能比我有更多的技能。我想到的是某种递归 cte 解决方案,你使用 @@SCOPE_IDENTITY 或适当的风格来播种递归。尽管我不敢建议,但光标是否适合您?我可以看到工作得很好。
  • 您能澄清一下“旧 ID”是什么意思吗?我不明白插入语句如何具有“旧 ID”?

标签: sql sql-server database tsql merge


【解决方案1】:

我最近不得不重新访问这段代码以进行更改,我所做的是:code (1) create table #tmptable ([oldID] [bigint] ,[newID] [bigint] ), (2) add主表的 oldID 永久列,与该行的 PK 完全相同 (3) INSERT INTO [dbo].[main table] OUTPUT inserted.[oldID],inserted.[newID] INTO #tmptable SELECT oldID , column1, column2 ... code - 这是为新 ID 和旧 ID 插入的数据出现在同一行的唯一方法,我很惊讶 msft 在 sql 中还没有这个命令因为合并非常慢!

【讨论】:

    猜你喜欢
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多