修复 table 的过程将 cci 构建为 ci

Procedure to fix table builds cci to ci

我们所有的平台团队都要求我们的团队不要使用不必要的 Clustered Columnstore

我正在尝试创建一个我们可以使用的过程 传入 table 和索引列。

我在尝试创建时遇到错误 “第 25 行第 14 列的解析错误:‘@A’附近的语法不正确”

我没有发现任何问题;我错过了什么?

GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROC [lab03].[Sproc_TableCCItoCI] @Table [NVARCHAR](150),@TheColumn [NVARCHAR](150) 
AS

-- exec lab03.Sproc_TableCCItoCI @param1 = '', @param2 = '' 



-- ==========================================================================================================================================================================
-- File Name:   
--  
-- Purpose: Fix tables built using clustered - columnstore 

-- 
-- Version  Date        Changed by              Description
-- -------  ----------  -------------------     -------------------------------------------
-- 1.0      2021-07-22  Sxxx                Move to prod 
-- 
-- ==========================================================================================================================================================================
-- converting Clustered Columnstore(CCI) index to Clustered Index (CI) 

DECLARE @A Varchar(6)
SET @A = 'lab16.'


CREATE TABLE @A + @Table + '_convert'  
WITH (   
       DISTRIBUTION = HASH (@TheColumn),
       CLUSTERED INDEX  (@TheColumn)
)
AS  
SELECT  
    * 
FROM @A + @Table 

--save current table just in case, you’ll drop this as soon as process is complete
  RENAME OBJECT @A + @Table TO  @Table + '_Hold'  
--renames new table to the existing name
RENAME OBJECT @A + @Table + '_convert'  TO @Table;   

--validate if desired then drop the hold table
DROP TABLE @A + @Table +'_Hold';



GO



我认为您需要更好地理解动态 SQL,我强烈推荐 Erland Sommarskog 的优秀文章“The Curse and Blessings of Dynamic SQL”。

我从我们的 Synapse 数据库中改编了一个例子,它正在做类似的事情,并展示了一种参数化动态 sql 的方法,并在 Synapse 中进行了一些错误检查,这在出现问题时是值得的。专用 SQL 池目前不支持 RETURN 语句,因此在发生错误时只是一种犁,所以最好通过错误消息收集尽可能多的信息。看看你对此有何看法:

IF OBJECT_ID('dbo.usp_convertTableToCI') IS NOT NULL
DROP PROC dbo.usp_convertTableToCI;
GO

CREATE PROC dbo.usp_convertTableToCI

    @schemaName SYSNAME, 
    @tableName SYSNAME,
    @columnName SYSNAME,
    @debug_yn BIT

AS

DECLARE @sql NVARCHAR(MAX);

SET NOCOUNT ON;

-- Check schema exists
IF NOT EXISTS ( SELECT * FROM sys.schemas WHERE [name] = @schemaName )
    RAISERROR( 'Source schema [%s] does not exist.', 16, 1, @schemaName );

-- Check table exists
IF NOT EXISTS ( SELECT * FROM sys.tables WHERE SCHEMA_NAME(schema_id) = @schemaName AND [name] = @tableName )
    RAISERROR( 'Source table [%s].[%s] does not exist.', 16, 1, @schemaName, @tableName );

-- Check column exists
IF NOT EXISTS ( SELECT * FROM sys.columns WHERE OBJECT_SCHEMA_NAME(object_id) = @schemaName AND OBJECT_NAME(object_id) = @tableName AND [name] = @columnName )
    RAISERROR( 'Column [%s] does not exist in table [%s].[%s].', 16, 1, @columnName, @schemaName, @tableName );


-- Assemble the dynamic SQL to swap the table over to clustered index
SET @sql = 'CREATE TABLE @schemaName.@tableName_convert  
WITH (
    DISTRIBUTION = HASH ( @columnName ),
    CLUSTERED INDEX ( @columnName )
)
AS
SELECT *
FROM @schemaName.@tableName;

-- Save current table just in case, you’ll drop this as soon as process is complete
RENAME OBJECT @schemaName.@tableName TO  @tableName_Hold

-- Renames new table to the existing name
RENAME OBJECT @schemaName.@tableName_convert TO @tableName;   

-- Validate if desired then drop the hold table
--DROP TABLE @schemaName.@tableName_Hold;'

-- Replace the variable names
SET @sql = REPLACE( 
    REPLACE( 
        REPLACE( @sql, '@schemaName', @schemaName ), 
            '@tableName', @tableName ), 
        '@columnName', @columnName )


IF @debug_yn = 1
    PRINT @sql;
ELSE
BEGIN
    PRINT @sql;
    EXEC(@sql);
END
GO

我强烈建议针对您的场景对其进行一些彻底的测试。