存储过程不执行Columnstored Index的drop语句

时间:2015-08-10 12:08:36

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

我在TbName上有一个Columnstored Non-Clustered Index,我在存储过程中有这个语句。当我执行存储过程时,控件似乎没有进入Drop语句。

SQL Server columnstore index update/insert in stored procedure。这个链接确实解释了原因,但我正在寻找解决方法。

有任何帮助吗?

IF EXISTS(SELECT * FROM sys.indexes WHERE object_id = object_id('TbName') AND NAME ='Index')
BEGIN
    DROP INDEX [Index] ON [TbName];
END   

下面添加我的SQL脚本片段
--Example Procedure
CREATE PROC DropIndexCheck
AS
BEGIN TRY

IF EXISTS(SELECT * FROM sys.indexes WHERE object_id = object_id('temp.FactMetric') AND NAME ='INXCU_FactMetric')
        BEGIN
            DROP INDEX [INXCU_FactMetric] ON [temp].[FactMetric];
        END

        IF EXISTS(SELECT * FROM sys.indexes WHERE object_id = object_id('temp.FactMetric') AND NAME ='INXCU_FactMetric')
        BEGIN
            EXEC sp_executesql N'DROP INDEX INXCU_FactMetric ON temp.FactMetric';
        END

    INSERT INTO [temp].[FactMetric]
        (
            [BuildVersionID]
          ,[EntityID]
          ,[MetricTypeID]
          ,[AdjustmentTypeID]
          ,[CurrencyID]
          ,[SecondaryClassID]
          ,[YOA]
          ,[MetricID]
          ,[BFWD]
          ,[CFWD]
          ,[Movement]

        )
    SELECT 
        1,1,1,1,1,1,1,1,1,1,1

END TRY
BEGIN CATCH

EXEC [qa].[uspRethrowError] @@PROCID;
END CATCH;


--Execute the Script Here
EXEC DropIndexCheck

我能够为此做一个解决方法:(不确定这是否是最佳方式,但有效)

在调用存储过程之前使用相同的Exists条件:

--Call the Drop Exists before calling the stored procedure
 IF EXISTS(SELECT * FROM sys.indexes WHERE object_id = object_id('temp.FactMetric') AND NAME ='INXCU_FactMetric')
            BEGIN
                DROP INDEX [INXCU_FactMetric] ON [temp].[FactMetric];
            END

EXEC DropIndexCheck

在这种情况下,Index将在执行存储过程之前被删除,插入不会中断。

1 个答案:

答案 0 :(得分:0)

此存储过程正常工作:

Create schema CS
Go
Create Table CS.CS_Table(col1 int, col2 int)
Go

Alter Proc CS.CS_proc_Drop
As 
Begin
    Declare @schema sysname = N'CS', @table sysname = N'CS_Table', @index sysname = N'CS_Table_Index'

    IF Exists(Select 1 From sys.indexes where OBJECT_NAME(object_id) = @table and OBJECT_SCHEMA_NAME(object_id) = @schema and name = @index)
    Begin
        Print 'drop'
        Drop Index [CS_Table_Index] on [CS].[CS_Table]
    End

    Insert Into [CS].[CS_Table](col1, col2) Select 1, 1

    IF Not Exists(Select 1 From sys.indexes where OBJECT_NAME(object_id) = @table and OBJECT_SCHEMA_NAME(object_id) = @schema and name = @index)
    Begin
        Print 'Create'
        Create nonclustered columnstore index [CS_Table_Index] on [CS].[CS_Table](col1)
    End
End
Go

exec CS.CS_proc_drop
select top 10 * from CS.CS_Table
Go

我让它工作(失败......)并且可以重现它。在检查过程时,索引不能在编译时出现。它适用于:

  • 我在创建/更改
  • 后手动删除索引
  • 该程序未重新编译
  • 我没有执行DBCC FREEPROCCACHE
  • 插入发生在子过程或动态SQL

如果索引存在,它会在重新编译时失败。

您应该在drop index之后立即从Proc1调用Proc2,Proc2将执行插入和索引创建。 您也可以先运行Proc1,然后运行Proc2。

事实上,这与您在问题中所提供的链接中的内容类似。