合并语句

时间:2016-01-08 10:57:57

标签: sql-server azure azure-sql-database

我有一个简单的合并语句的查询来更新或插入表中的数据:

MERGE INTO table_name AS TARGET
USING (
    VALUES (
        :a0
        ,:b0
        ,:c0
        )...
    ) AS SOURCE(A, B, C)
    ON SOURCE.B = TARGET.B
        AND SOURCE.C = TARGET.C
WHEN NOT MATCHED
    THEN
        INSERT (
            A
            ,B
            ,C
            )
        VALUES (
            SOURCE.A
            ,SOURCE.B
            ,SOURCE.C
            );

此表在两列上具有唯一性约束的非聚簇索引。 此查询在Azure中的“业务”数据库上正常工作。在“S2”数据库上迁移到SQL V12后,当我尝试合并大量条目时会发生此错误:

  

带有消息'SQLSTATE [42000]的未捕获异常'PDOException':[Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]无法批量加载。批量数据流被错误地指定为已排序或数据违反了目标表强加的唯一性约束。以下两行的排序顺序不正确:第一行的主键:(A,B,C),第二行的主键:(A,D,E)。

微软似乎知道这个问题:https://support.microsoft.com/en-us/kb/3055799

但在Azure中,我无法更新SQL Server。我怎样才能让它发挥作用?

3 个答案:

答案 0 :(得分:1)

经过一些研究和测试后,我在查询结束时添加了一个解决方法" OPTION(LOOP JOIN,FORCE ORDER);"通过修改默认执行计划来绕过排序错误。

它也适用于" OPTION(MERGE JOIN,FORCE ORDER);"取决于源和目标表的行数。

有关选项的更多信息:https://technet.microsoft.com/en-us/library/ms181714.aspx

答案 1 :(得分:0)

我们发现查询优化器生成的执行计划存在问题。 这将很快修复。

同时解决此问题的另一个选项是禁用索引上的page_lock。

ALTER INDEX [<index name>] ON [<schema>].[<table name>] 
REBUILD WITH (ALLOW_PAGE_LOCKS = OFF) 

通过此解决方法,您无需修改​​查询。

答案 2 :(得分:0)

你好@Yochanan Rachamim,

感谢您的回答。

我尝试应用您的修复,但它没有任何效果。 经过更多的研究,我发现了一个已知的并发错误:https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

我终于通过在MERGE语句中添加“WITH(HOLDLOCK)”解决了我的问题。