ALTER INDEX语句被忽略了吗?

时间:2014-05-15 16:55:03

标签: sql-server tsql sql-server-2012

当我运行下面的伪代码时:

BEGIN TRANSACTION @TName
BEGIN TRY
    -- Disable columnstore index
    ALTER INDEX CSIX_MyTable ON dbo.MyTable DISABLE;

    MERGE INTO dbo.MyTable

...

我收到此错误:

  

MERGE语句失败,因为无法在具有列存储索引的表中更新数据。考虑在发出MERGE语句之前禁用列存储索引,然后在MERGE完成后重建列存储索引。

我不明白的是,在执行MERGE之前,我明确禁用了索引。我已经检查过双倍,三倍和四倍,我禁用了正确的索引。实际上,如果我自己执行ALTER INDEX语句然后再次运行上面的块,MERGE就完成了。关于为什么会这样或者我如何解决它的任何想法?

修改

我还有以下伪代码执行没有问题:

BEGIN TRANSACTION @TName
BEGIN TRY
    -- Disable columnstore index
    ALTER INDEX CSIX_MyTable2 ON dbo.MyTable2 DISABLE;

    INSERT INTO #MyTempTable(Columns...)
    SELECT Columns...
    FROM (
        MERGE INTO dbo.MyTable
        ...
        OUTPUT ...
    ) A

...

索引被禁用,MERGE进程顺利完成。似乎由于某种原因,包装INSERT语句出现在"技巧"编译器执行代码。

我确定将ALTER INDEX语句移动到另一个任务将解决问题,但我对此问题的希望是尝试发现为什么代码不会按原样运行。

3 个答案:

答案 0 :(得分:1)

猜测:代码在编译时被拒绝。 SQL接受你的脚本,解析它,看到合并,确定有一个列存储索引,然后引发并返回错误......而不是足够聪明地注意"注意"在前一步骤中禁用了索引。

我不知道这是问题,但我之前已经看过这样的问题。

答案 1 :(得分:0)

使用列存储索引的一个限制是,如果不禁用或删除表中的列存储索引,则无法更新表。

一个建议是在事务语句之前使用disable columnstore index语句。 您也可以尝试删除列存储索引,然后再重新创建它。

答案 2 :(得分:-1)

您需要使用动态SQL来更新表。正如在另一个答案中所提到的,这是一个编译错误