tsql生成索引创建文本,然后对其求值

tsql生成索引创建文本,然后对其求值,tsql,Tsql,我有一个脚本,它根据我们接收到的数据创建和填充一组表 文本文件。将数据加载到SQLServer2008后,我想添加索引。我使用的剪切粘贴创建脚本如下所示 是 TSQL中有一种方法可以创建一个函数,该函数将生成 评估DDL命令?该函数将采用参数 表名、列名和聚集/非聚集。如果有 要成为1列/2列索引的单独函数,我仍然需要 有兴趣 我的设想是: hypotheticalFunction('clustered', 'precCdaEarn', 'account', 'seq') hypotherica

我有一个脚本,它根据我们接收到的数据创建和填充一组表 文本文件。将数据加载到SQLServer2008后,我想添加索引。我使用的剪切粘贴创建脚本如下所示

是 TSQL中有一种方法可以创建一个函数,该函数将生成 评估DDL命令?该函数将采用参数 表名、列名和聚集/非聚集。如果有 要成为1列/2列索引的单独函数,我仍然需要 有兴趣

我的设想是:

hypotheticalFunction('clustered', 'precCdaEarn', 'account', 'seq')
hypothericalFunction('nonClustered', 'flats', 'vendorAcct')
IF(OBJECT_ID('PRC_CREATE_INDEX', N'P') IS NOT NULL)
    DROP PROCEDURE PRC_CREATE_INDEX
GO

CREATE PROCEDURE dbo.PRC_CREATE_INDEX 
(
    -- Table name to add index to
    @pTablename AS VARCHAR(120)

    -- Index name to add/change
,   @pIndexname AS VARCHAR(120)         

    -- UNIQUE, CLUSTERED or other definition
,   @pNewIndexDef AS VARCHAR(255) = ''

    -- Columns in index     
,   @pNewIndexCols AS VARCHAR(255)

    -- Recreate even if same 
,   @pForceRecreate AS SMALLINT = 0

    -- Additional columns for INCLUDE
,   @pColumnsInclude AS VARCHAR(255) = ''
)
AS

------------------------------------
--  Variabels
------------------------------------
    DECLARE @SQL_DROP AS NVARCHAR(1000)
    ,   @SQL_CREATE AS NVARCHAR(1000)
    ,   @retval AS INTEGER
    ,   @rowcount AS INTEGER

    DECLARE @oldDescription AS VARCHAR(255)
    ,   @newUnique AS SMALLINT
    ,   @newClustered AS SMALLINT
    ,   @newIndexDef AS VARCHAR(255)
    ,   @newDescription AS VARCHAR(255)
    ,   @drop_index AS BIT
    ,   @temp AS VARCHAR(MAX)


------------------------------------
--  Initiate
------------------------------------
    SET XACT_ABORT ON
    SET NOCOUNT ON


-- Table exists?

    IF(OBJECT_ID(@pTablename) IS NULL)
    BEGIN
        PRINT   'Error: Table does not exist: ' + @pTablename + 
            ' ('  + 'creation of index ''' + @pTablename +  '.' + @pIndexname + ''')'
        RETURN (1)
    END


-----------------------------------------------------------------------------------------------------
-- New index
-----------------------------------------------------------------------------------------------------


-- Initiate (Remove blanks, get unique/clustered info)

    SELECT  @newIndexDef = @pNewIndexDef
    -- Remove NONCLUSTERED
    ,   @newIndexDef = REPLACE(@newIndexDef, 'nonclustered', '')
    -- CLUSTERED?
    ,   @newClustered = CASE WHEN PATINDEX('%clustered%', LOWER(@newIndexDef)) > 0 THEN 1 ELSE 0 END
    ,   @newIndexDef = REPLACE(@newIndexDef, 'clustered', '')
    -- UNIQUE?
    ,   @newUnique = CASE WHEN PATINDEX('%unique%', LOWER(@pNewIndexDef)) > 0 THEN 1 ELSE 0 END
    ,   @newIndexDef = REPLACE(@newIndexDef, 'unique', '')
    -- Remove blanks etc.
    ,   @pNewIndexCols = REPLACE(@pNewIndexCols, ' DESC', '#DESC')
    ,   @newIndexDef = REPLACE(@newIndexDef, ' ', '')
    ,   @newIndexDef = REPLACE(@newIndexDef, ',', '')
    ,   @pNewIndexCols = REPLACE(@pNewIndexCols, ' ', '')
    ,   @pColumnsInclude = REPLACE(@pColumnsInclude, ' ', '')


-- Correct defintion?

    IF LEN(@newIndexDef) > 0
    BEGIN
        RAISERROR ('Index defintion ''%s'' is incorrect for index ''%s.%s''!', 11, 11, @pNewIndexDef, @pTablename, @pIndexname)
        RETURN (1)
    END     

    IF @newClustered = 1 AND LEN(@pColumnsInclude) > 0
    BEGIN
        RAISERROR ('Cannot specify included columns for a clustered index (''%s.%s'')!', 11, 11, @pIndexname, @pTablename)
        RETURN (1)
    END

    IF @pNewIndexCols LIKE '%#DESC%'
    BEGIN
        RAISERROR ('Descending sort direction not supported (''%s.%s'')!', 11, 11, @pTablename, @pIndexname)
        RETURN (1)
    END

    IF  @newClustered = 1 AND EXISTS
    ( 
        SELECT  1
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name <> @pIndexname
        AND type = 1            -- CLUSTERED
        AND is_hypothetical = 0
    )   
    BEGIN
        SELECT  @temp = name
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name <> @pIndexname
        AND type = 1            -- CLUSTERED
        AND is_hypothetical = 0

        RAISERROR ('Cannot add CLUSTERED index (''%s.%s'') - table already has a clustered index (''%s'')!', 11, 11, @pTablename, @pIndexname, @temp)
        RETURN (1)
    END


-- Prepare SQL

    -- CREATE
    SELECT  @SQL_CREATE = ''
    +   'CREATE '
    +   CASE WHEN @newUnique = 1 THEN 'UNIQUE ' ELSE '' END
    +   CASE WHEN @newClustered = 1 THEN 'CLUSTERED ' ELSE 'NONCLUSTERED ' END
    +   'INDEX ' + @pIndexname + ' '
    +   'ON ' + @pTablename + ' ' 
    +   '(' + @pNewIndexCols + ')'
    +   CASE WHEN LEN(@pColumnsInclude) > 0 THEN ' INCLUDE (' + @pColumnsInclude + ')' ELSE '' END

    -- Description
    SELECT  @newDescription = ''
    +   CASE WHEN @newUnique = 1 THEN 'UNIQUE ' ELSE '' END
    +   CASE WHEN @newClustered = 1 THEN 'CLUSTERED ' ELSE 'NONCLUSTERED ' END
    +   '(' + @pNewIndexCols + ')'
    +   CASE WHEN LEN(@pColumnsInclude) > 0 THEN ' INCLUDE (' + @pColumnsInclude + ')' ELSE '' END

    -- DROP
    SET @SQL_DROP = ''
    +   'DROP INDEX ' + @pTablename
    +   '.' + @pIndexname



-----------------------------------------------------------------------------------------------------
-- Current index
-----------------------------------------------------------------------------------------------------

-- Initiate 

    SELECT  @drop_index = 0

-- Get definition/description and check if recreation is needed

    IF EXISTS
    (   
        SELECT  1
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name = @pIndexname
    )
    BEGIN   

    -- Description

        SELECT  @oldDescription = ''
        +   CASE WHEN i.is_unique = 1 THEN 'UNIQUE ' ELSE '' END
        +   CASE 
                WHEN    i.type = 1 THEN 'CLUSTERED ' 
                WHEN    i.type = 2 THEN 'NONCLUSTERED ' 
                ELSE    '? '
            END
        +   '(' + STUFF(
                (
                    SELECT  ',' + COL_NAME(ic.object_id, ic.column_id)
                    FROM    sys.index_columns ic (NOLOCK)
                    WHERE   ic.object_id = i.object_id
                    AND ic.index_id = i.index_id
                    AND ic.is_included_column = 0
                    ORDER   BY ic.key_ordinal
                    FOR XML PATH('')
                )
            , 1, 1, '') + ')'
        +   ISNULL(' INCLUDE (' + STUFF(
                (
                    SELECT  ',' + COL_NAME(ic.object_id, ic.column_id)
                    FROM    sys.index_columns ic (NOLOCK)
                    WHERE   ic.object_id = i.object_id
                    AND ic.index_id = i.index_id
                    AND ic.is_included_column = 1
                    ORDER   BY ic.index_column_id    -- Or column_id???
                    FOR XML PATH('')
                )
            , 1, 1, '') + ')', '')
        FROM    sys.indexes i (NOLOCK)
        WHERE   i.object_id = OBJECT_ID(@pTablename, N'U')
        AND i.name = @pIndexname

    -- Exit?

        -- If not changed and no force of recreation
        IF  @oldDescription = @newDescription
            AND
            @pForceRecreate = 0
        BEGIN       
            RETURN 0
        END


    -- We should drop current index..

        SET @drop_index = 1
    END



-----------------------------------------------------------------------------------------------------
-- Execute SQL
-----------------------------------------------------------------------------------------------------

-- Exec

    IF @drop_index = 1
        EXEC    sp_executesql @SQL_DROP

    IF LEN(@pNewIndexCols) > 0
        EXEC    sp_executesql @SQL_CREATE


-- Message

    IF LEN(@pNewIndexCols) > 0 AND @drop_index = 0
        PRINT   'Created index ' + @pTablename + '.' + @pIndexname + ' (' + @newDescription + ')'
    ELSE IF LEN(@pNewIndexCols) > 0 AND @drop_index = 1
        PRINT   'Recreated index ' + @pTablename + '.' + @pIndexname + CHAR(10) +
            '   From: ' + @oldDescription + CHAR(10) +
            '   To:   ' + @newDescription
    -- Well, this will perhaps occur when and if this proc is changed...
    ELSE IF @drop_index = 1
        PRINT 'Removed index ' + @pTablename + '.' + @pIndexname + ' (' + @oldDescription + ')'


-----------------------------------------------------------------------------------------------------
-- Exit
-----------------------------------------------------------------------------------------------------
    RETURN (0)
GO
这将检查表中是否存在名为“idx_acct_seq”的帐户 precCdaEarn,如果是,则删除它,然后将其创建为聚集索引。(把它扔了 以防我更改定义)。并在dbo.flats上创建/重新创建名为“idx_vendorAcct”的非聚集索引

=========这是我们现在使用的剪切粘贴,为不规则的间距表示歉意==============

IF EXISTS (Select 'X' 
  FROM sysindexes
    WHERE id = (SELECT OBJECT_ID('precCdaEarn'))
      and name = 'idx_account_seq')
     DROP index precCdaEarn.idx_account_seq 
   Create nonclustered index idx_account_seq
      ON precCdaEarn(account, seq)
)


当然,您不能为此创建函数,但是使用存储过程不会有问题

比如:

hypotheticalFunction('clustered', 'precCdaEarn', 'account', 'seq')
hypothericalFunction('nonClustered', 'flats', 'vendorAcct')
IF(OBJECT_ID('PRC_CREATE_INDEX', N'P') IS NOT NULL)
    DROP PROCEDURE PRC_CREATE_INDEX
GO

CREATE PROCEDURE dbo.PRC_CREATE_INDEX 
(
    -- Table name to add index to
    @pTablename AS VARCHAR(120)

    -- Index name to add/change
,   @pIndexname AS VARCHAR(120)         

    -- UNIQUE, CLUSTERED or other definition
,   @pNewIndexDef AS VARCHAR(255) = ''

    -- Columns in index     
,   @pNewIndexCols AS VARCHAR(255)

    -- Recreate even if same 
,   @pForceRecreate AS SMALLINT = 0

    -- Additional columns for INCLUDE
,   @pColumnsInclude AS VARCHAR(255) = ''
)
AS

------------------------------------
--  Variabels
------------------------------------
    DECLARE @SQL_DROP AS NVARCHAR(1000)
    ,   @SQL_CREATE AS NVARCHAR(1000)
    ,   @retval AS INTEGER
    ,   @rowcount AS INTEGER

    DECLARE @oldDescription AS VARCHAR(255)
    ,   @newUnique AS SMALLINT
    ,   @newClustered AS SMALLINT
    ,   @newIndexDef AS VARCHAR(255)
    ,   @newDescription AS VARCHAR(255)
    ,   @drop_index AS BIT
    ,   @temp AS VARCHAR(MAX)


------------------------------------
--  Initiate
------------------------------------
    SET XACT_ABORT ON
    SET NOCOUNT ON


-- Table exists?

    IF(OBJECT_ID(@pTablename) IS NULL)
    BEGIN
        PRINT   'Error: Table does not exist: ' + @pTablename + 
            ' ('  + 'creation of index ''' + @pTablename +  '.' + @pIndexname + ''')'
        RETURN (1)
    END


-----------------------------------------------------------------------------------------------------
-- New index
-----------------------------------------------------------------------------------------------------


-- Initiate (Remove blanks, get unique/clustered info)

    SELECT  @newIndexDef = @pNewIndexDef
    -- Remove NONCLUSTERED
    ,   @newIndexDef = REPLACE(@newIndexDef, 'nonclustered', '')
    -- CLUSTERED?
    ,   @newClustered = CASE WHEN PATINDEX('%clustered%', LOWER(@newIndexDef)) > 0 THEN 1 ELSE 0 END
    ,   @newIndexDef = REPLACE(@newIndexDef, 'clustered', '')
    -- UNIQUE?
    ,   @newUnique = CASE WHEN PATINDEX('%unique%', LOWER(@pNewIndexDef)) > 0 THEN 1 ELSE 0 END
    ,   @newIndexDef = REPLACE(@newIndexDef, 'unique', '')
    -- Remove blanks etc.
    ,   @pNewIndexCols = REPLACE(@pNewIndexCols, ' DESC', '#DESC')
    ,   @newIndexDef = REPLACE(@newIndexDef, ' ', '')
    ,   @newIndexDef = REPLACE(@newIndexDef, ',', '')
    ,   @pNewIndexCols = REPLACE(@pNewIndexCols, ' ', '')
    ,   @pColumnsInclude = REPLACE(@pColumnsInclude, ' ', '')


-- Correct defintion?

    IF LEN(@newIndexDef) > 0
    BEGIN
        RAISERROR ('Index defintion ''%s'' is incorrect for index ''%s.%s''!', 11, 11, @pNewIndexDef, @pTablename, @pIndexname)
        RETURN (1)
    END     

    IF @newClustered = 1 AND LEN(@pColumnsInclude) > 0
    BEGIN
        RAISERROR ('Cannot specify included columns for a clustered index (''%s.%s'')!', 11, 11, @pIndexname, @pTablename)
        RETURN (1)
    END

    IF @pNewIndexCols LIKE '%#DESC%'
    BEGIN
        RAISERROR ('Descending sort direction not supported (''%s.%s'')!', 11, 11, @pTablename, @pIndexname)
        RETURN (1)
    END

    IF  @newClustered = 1 AND EXISTS
    ( 
        SELECT  1
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name <> @pIndexname
        AND type = 1            -- CLUSTERED
        AND is_hypothetical = 0
    )   
    BEGIN
        SELECT  @temp = name
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name <> @pIndexname
        AND type = 1            -- CLUSTERED
        AND is_hypothetical = 0

        RAISERROR ('Cannot add CLUSTERED index (''%s.%s'') - table already has a clustered index (''%s'')!', 11, 11, @pTablename, @pIndexname, @temp)
        RETURN (1)
    END


-- Prepare SQL

    -- CREATE
    SELECT  @SQL_CREATE = ''
    +   'CREATE '
    +   CASE WHEN @newUnique = 1 THEN 'UNIQUE ' ELSE '' END
    +   CASE WHEN @newClustered = 1 THEN 'CLUSTERED ' ELSE 'NONCLUSTERED ' END
    +   'INDEX ' + @pIndexname + ' '
    +   'ON ' + @pTablename + ' ' 
    +   '(' + @pNewIndexCols + ')'
    +   CASE WHEN LEN(@pColumnsInclude) > 0 THEN ' INCLUDE (' + @pColumnsInclude + ')' ELSE '' END

    -- Description
    SELECT  @newDescription = ''
    +   CASE WHEN @newUnique = 1 THEN 'UNIQUE ' ELSE '' END
    +   CASE WHEN @newClustered = 1 THEN 'CLUSTERED ' ELSE 'NONCLUSTERED ' END
    +   '(' + @pNewIndexCols + ')'
    +   CASE WHEN LEN(@pColumnsInclude) > 0 THEN ' INCLUDE (' + @pColumnsInclude + ')' ELSE '' END

    -- DROP
    SET @SQL_DROP = ''
    +   'DROP INDEX ' + @pTablename
    +   '.' + @pIndexname



-----------------------------------------------------------------------------------------------------
-- Current index
-----------------------------------------------------------------------------------------------------

-- Initiate 

    SELECT  @drop_index = 0

-- Get definition/description and check if recreation is needed

    IF EXISTS
    (   
        SELECT  1
        FROM    sys.indexes (NOLOCK)
        WHERE   object_id = OBJECT_ID(@pTablename, N'U')
        AND name = @pIndexname
    )
    BEGIN   

    -- Description

        SELECT  @oldDescription = ''
        +   CASE WHEN i.is_unique = 1 THEN 'UNIQUE ' ELSE '' END
        +   CASE 
                WHEN    i.type = 1 THEN 'CLUSTERED ' 
                WHEN    i.type = 2 THEN 'NONCLUSTERED ' 
                ELSE    '? '
            END
        +   '(' + STUFF(
                (
                    SELECT  ',' + COL_NAME(ic.object_id, ic.column_id)
                    FROM    sys.index_columns ic (NOLOCK)
                    WHERE   ic.object_id = i.object_id
                    AND ic.index_id = i.index_id
                    AND ic.is_included_column = 0
                    ORDER   BY ic.key_ordinal
                    FOR XML PATH('')
                )
            , 1, 1, '') + ')'
        +   ISNULL(' INCLUDE (' + STUFF(
                (
                    SELECT  ',' + COL_NAME(ic.object_id, ic.column_id)
                    FROM    sys.index_columns ic (NOLOCK)
                    WHERE   ic.object_id = i.object_id
                    AND ic.index_id = i.index_id
                    AND ic.is_included_column = 1
                    ORDER   BY ic.index_column_id    -- Or column_id???
                    FOR XML PATH('')
                )
            , 1, 1, '') + ')', '')
        FROM    sys.indexes i (NOLOCK)
        WHERE   i.object_id = OBJECT_ID(@pTablename, N'U')
        AND i.name = @pIndexname

    -- Exit?

        -- If not changed and no force of recreation
        IF  @oldDescription = @newDescription
            AND
            @pForceRecreate = 0
        BEGIN       
            RETURN 0
        END


    -- We should drop current index..

        SET @drop_index = 1
    END



-----------------------------------------------------------------------------------------------------
-- Execute SQL
-----------------------------------------------------------------------------------------------------

-- Exec

    IF @drop_index = 1
        EXEC    sp_executesql @SQL_DROP

    IF LEN(@pNewIndexCols) > 0
        EXEC    sp_executesql @SQL_CREATE


-- Message

    IF LEN(@pNewIndexCols) > 0 AND @drop_index = 0
        PRINT   'Created index ' + @pTablename + '.' + @pIndexname + ' (' + @newDescription + ')'
    ELSE IF LEN(@pNewIndexCols) > 0 AND @drop_index = 1
        PRINT   'Recreated index ' + @pTablename + '.' + @pIndexname + CHAR(10) +
            '   From: ' + @oldDescription + CHAR(10) +
            '   To:   ' + @newDescription
    -- Well, this will perhaps occur when and if this proc is changed...
    ELSE IF @drop_index = 1
        PRINT 'Removed index ' + @pTablename + '.' + @pIndexname + ' (' + @oldDescription + ')'


-----------------------------------------------------------------------------------------------------
-- Exit
-----------------------------------------------------------------------------------------------------
    RETURN (0)
GO

哇,太慷慨了,我希望你自己也能用上。我每年做12-20个项目,将其他供应商的数据库转换为我们产品的数据库,并使用sql server准备数据。我可能会在每个项目中使用这个。如果我有什么要补充的,我会在这里提到,因为现在它正是我想要的。谢谢。除了我剥去了一些私人的部分,它被广泛使用;)