T-SQL脚本错误

时间:2015-07-03 10:48:15

标签: sql-server tsql stored-procedures

我正在尝试在存储过程下面运行,但是如果失败并出现以下错误

受影响的2行

(1行受影响)

(受影响的1行)消息102,级别15,状态1,过程isp_ALTER_INDEX,行108'列附近的语法不正确。 消息102,级别15,状态1,过程isp_ALTER_INDEX,行197错误语法附近'结束'。
消息2812,级别16,状态62,行1无法找到存储过程' isp_ALTER_INDEX'。

 USE master
    GO
    IF OBJECT_ID('dbo.DefragmentIndexes') IS NULL GOTO CreateTable
    DECLARE @ArchiveTableName SYSNAME = 'DefragmentIndexes_Old'
    IF EXISTS (SELECT * FROM sys.tables WHERE name = N'DefragmentIndexes_Old')
    DROP TABLE dbo.DefragmentIndexes_Old
    EXEC sp_rename N'dbo.DefragmentIndexes', @ArchiveTableName, N'OBJECT';
    DECLARE @indexes TABLE (LineID INT NOT NULL IDENTITY(1,1), index_name SYSNAME)
    INSERT @indexes
    SELECT i.name
    FROM sys.indexes i
    WHERE i.object_id = OBJECT_ID(@ArchiveTableName)
    AND i.index_id <> 1
    DECLARE @i INT, @index_name SYSNAME
    SELECT TOP(1) @i = LineId, @index_name = index_name FROM @indexes
    WHILE @i IS NOT NULL
    BEGIN
    EXEC('DROP INDEX ' + @ArchiveTableName + '.' + @index_name)
    DELETE @indexes WHERE LineID = @i
    SET @i = NULL
    SELECT TOP(1) @i = LineId, @index_name = index_name FROM @indexes
    END
    CreateTable:
    CREATE TABLE DefragmentIndexes
    (
    LineId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    DatabaseName SYSNAME NOT NULL,
    SchemaName SYSNAME NOT NULL,
    TableName SYSNAME NOT NULL,
    IndexName SYSNAME NOT NULL,
    DefragmentDate datetime NOT NULL,
    PercentFragmented decimal(4, 2) NOT NULL,
    )
    GO
    IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name =
    'nci_DefragmentIndexes_DefragmentDate')
    CREATE INDEX nci_DefragmentIndexes_DefragmentDate
    ON DefragmentIndexes (DefragmentDate)
    INCLUDE (SchemaName, TableName)
    GO
    IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name =
    'nci_DefragmentIndexes_TableName_SchemaName')
    CREATE INDEX nci_DefragmentIndexes_TableName_SchemaName
    ON DefragmentIndexes (TableName, SchemaName)
    INCLUDE (DefragmentDate)
    IF OBJECT_ID(N'[dbo].[isp_ALTER_INDEX]') IS NOT NULL
    DROP PROC [dbo].[isp_ALTER_INDEX]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROC [dbo].[isp_ALTER_INDEX]
    (
    @dbName sysname,
    @statsMode varchar(8) = 'SAMPLED',
    @defragType varchar(10) = 'REORGANIZE',
    @minFragPercent int = 25,
    @maxFragPercent int = 100,
    @minRowCount int = 0,
    @logHistory bit = 0,
    @sortInTempdb bit = 0
    )
    AS
    SET NOCOUNT ON
    IF @statsMode NOT IN ('LIMITED', 'SAMPLED', 'DETAILED')
    BEGIN
    RAISERROR('@statsMode must be LIMITED, SAMPLED or DETAILED', 16, 1)
    RETURN
    END
    IF @defragType NOT IN ('REORGANIZE', 'REBUILD')
    BEGIN
    RAISERROR('@defragType must be REORGANIZE or REBUILD', 16, 1)
    RETURN
    END
    DECLARE
    @i int, @objectId int, @objectName sysname, @indexId int, @indexName
    sysname,
    @schemaName sysname, @partitionNumber int, @partitionCount int,
    @sql nvarchar(4000), @edition int, @parmDef nvarchar(500), @allocUnitType
    nvarchar(60),
    @indexType nvarchar(60), @online bit, @disabled bit, @dataType
    nvarchar(128),
    @charMaxLen int, @allowPageLocks bit, @lobData bit, @fragPercent float
    SELECT @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
    SELECT
    IDENTITY(int, 1, 1) AS FragIndexId,
    [object_id] AS ObjectId,
    index_id AS IndexId,
    avg_fragmentation_in_percent AS FragPercent,
    record_count AS RecordCount,
    partition_number AS PartitionNumber,
    index_type_desc AS IndexType,
    alloc_unit_type_desc AS AllocUnitType
    INTO #FragIndex
    FROM sys.dm_db_index_physical_stats (DB_ID(@dbName), NULL, NULL, NULL,
    @statsMode)
    WHERE
    avg_fragmentation_in_percent > @minFragPercent AND
    avg_fragmentation_in_percent < @maxFragPercent AND
    index_id > 0 AND
    index_level = 0
    ORDER BY ObjectId
    IF @statsMode IN ('SAMPLED', 'DETAILED')
    DELETE FROM #FragIndex
    WHERE RecordCount < @minRowCount
    SELECT @i = MIN(FragIndexId)
    FROM #FragIndex
    SELECT
    @objectId = ObjectId,
    @indexId = IndexId,
    @fragPercent = FragPercent,
    @partitionNumber = PartitionNumber,
    @indexType = IndexType,
    @allocUnitType = AllocUnitType
    FROM #FragIndex
    WHERE FragIndexId = @i
    WHILE @@ROWCOUNT <> 0
    BEGIN
    SET @sql = '
    SELECT @objectName = o.[name], @schemaName = s.[name]
    FROM ' + QUOTENAME(@dbName) + '.sys.objects o
    JOIN ' + QUOTENAME(@dbName) + '.sys.schemas s
    ON s.schema_id = o.schema_id
    WHERE o.[object_id] = @objectId'
    SET @parmDef = N'@objectId int, @objectName sysname OUTPUT, @schemaName
    sysname OUTPUT'
    EXEC sp_executesql
    @sql, @parmDef, @objectId = @objectId,
    @objectName = @objectName OUTPUT, @schemaName = @schemaName OUTPUT
    SET @sql = '
    SELECT @indexName = [name], @disabled = is_disabled, @allowPageLocks =
    allow_page_locks
    FROM ' + QUOTENAME(@dbName) + '.sys.indexes
    WHERE [object_id] = @objectId AND index_id = @indexId'
    SET @parmDef = N'
    @objectId int, @indexId int, @indexName sysname OUTPUT,
    @disabled bit OUTPUT, @allowPageLocks bit OUTPUT'
    EXEC sp_executesql
    @sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
    @indexName = @indexName OUTPUT, @disabled = @disabled OUTPUT,
    @allowPageLocks = @allowPageLocks OUTPUT
    SET @lobData = 0
    IF @indexType = 'CLUSTERED INDEX'
    BEGIN
    SET @sql = '
    SELECT @lobData = 1
    FROM ' + QUOTENAME(@dbName) + '.INFORMATION_SCHEMA.COLUMNS c
    WHERE TABLE_SCHEMA = @schemaName AND
    TABLE_NAME = @objectName AND
    (DATA_TYPE IN (''text'', ''ntext'', ''image'') OR
    CHARACTER_MAXIMUM_LENGTH = -1)'
    SET @parmDef = N'@schemaName sysname, @objectName sysname, @lobData
    bit OUTPUT'
    EXEC sp_executesql
    @sql, @parmDef, @schemaName = @schemaName, @objectName =
    @objectName,
    @lobData = @lobData OUTPUT
    END
    columns
    ELSE IF @indexType = 'NONCLUSTERED INDEX'
    BEGIN
    SET @sql = '
    SELECT @lobData = 1
    FROM ' + QUOTENAME(@dbName) + '.sys.indexes i
    JOIN ' + QUOTENAME(@dbName) + '.sys.index_columns ic
    ON i.object_id = ic.object_id
    JOIN ' + QUOTENAME(@dbName) + '.INFORMATION_SCHEMA.COLUMNS c
    ON ic.column_id = c.ORDINAL_POSITION
    WHERE c.TABLE_SCHEMA = @schemaName AND
    c.TABLE_NAME = @objectName AND
    i.name = @indexName AND
    ic.is_included_column = 1 AND
    (c.DATA_TYPE IN (''text'', ''ntext'', ''image'')
    OR c.CHARACTER_MAXIMUM_LENGTH = -1)'
    SET @parmDef = N'@schemaName sysname, @objectName sysname,
    @indexName sysname, @lobData bit OUTPUT'
    EXEC sp_executesql
    @sql, @parmDef, @schemaName = @schemaName, @objectName =
    @objectName,
    @indexName = @indexName, @lobData = @lobData OUTPUT
    END
    SET @sql = '
    SELECT @partitionCount = COUNT(*)
    FROM ' + QUOTENAME(@dbName) + '.sys.partitions
    WHERE [object_id] = @objectId AND index_id = @indexId'
    SET @parmDef = N'@objectId int, @indexId int, @partitionCount int OUTPUT'
    EXEC sp_executesql
    @sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
    @partitionCount = @partitionCount OUTPUT
    IF @edition = 3 AND (@defragType = 'REBUILD' OR (@defragType =
    'REORGANIZE' AND @allowPageLocks = 0))
    BEGIN
    SET @online =
    CASE
    WHEN @indexType IN ('XML INDEX', 'PRIMARY XML
    INDEX') THEN 0
    WHEN @indexType = 'NONCLUSTERED INDEX' AND
    @allocUnitType = 'LOB_DATA' THEN 0
    WHEN @lobData = 1 THEN 0
    WHEN @disabled = 1 THEN 0
    WHEN @partitionCount > 1 THEN 0
    ELSE 1
    END
    END
    ELSE
    SET @online = 0
    SET @sql = 'ALTER INDEX ' + QUOTENAME(@indexName) + ' ON ' +
    QUOTENAME(@dbName) + '.' +
    QUOTENAME(@schemaName) + '.' + QUOTENAME(@objectName) +
    CASE
    WHEN @defragType = ' REORGANIZE' AND @allowPageLocks = 0 THEN
    ' REBUILD'
    ELSE ' ' + @defragType
    END
    IF @online = 1 OR @sortInTempdb = 1
    BEGIN
    SET @sql = @sql + ' WITH (' +
    CASE
    WHEN @online = 1 AND @sortInTempdb = 1 THEN 'ONLINE =
    ON, SORT_IN_TEMPDB = ON'
    WHEN @online = 1 AND @sortInTempdb = 0 THEN 'ONLINE =
    ON'
    WHEN @online = 0 AND @sortInTempdb = 1 THEN
    'SORT_IN_TEMPDB = ON'
    END + ')'
    END
    IF @partitionCount > 1 AND @disabled = 0 AND @indexType <> 'XML INDEX'
    SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS
    varchar(10))
    EXEC (@SQL)
    IF @logHistory = 1
    INSERT INTO DefragmentIndexes (DatabaseName, SchemaName, TableName,
    IndexName, DefragmentDate, PercentFragmented)
    VALUES(@dbName, @schemaName, @objectName, @indexName, GETDATE(),
    @fragPercent)
    SELECT @i = MIN(FragIndexId)
    FROM #FragIndex
    WHERE FragIndexId > @i
    SELECT
    @objectId = ObjectId,
    @indexId = IndexId,
    @fragPercent = FragPercent,
    @partitionNumber = PartitionNumber,
    @indexType = IndexType,
    @allocUnitType = AllocUnitType
    FROM #FragIndex
    WHERE FragIndexId = @i
    END
    GO
    EXEC isp_ALTER_INDEX
    @dbName = 'MODEV',
    @statsMode = 'SAMPLED',
    @defragType = 'REBUILD',
    @minFragPercent = 1,
    @maxFragPercent = 100,
    @minRowCount = 10,
    @logHistory = 1,
    @sortInTempdb = 1
    GO

1 个答案:

答案 0 :(得分:2)

首先。只是糟糕代码格式化!毫无疑问,您在这个批量代码中看不到任何错误。有一些基本的代码错误。我在下面的陈述中修正了它们。其中一个就是这样:

EXEC sp_executesql
    @sql, @parmDef, @schemaName = @schemaName, @objectName =
    @objectName,
    @lobData = @lobData OUTPUT
    END
columns -- Why columns? This has no context!
ELSE ...

请改为尝试:

USE master
GO

IF OBJECT_ID('dbo.DefragmentIndexes') IS NULL GOTO CreateTable

DECLARE @ArchiveTableName SYSNAME = 'DefragmentIndexes_Old'

IF EXISTS (SELECT * FROM sys.tables WHERE name = N'DefragmentIndexes_Old')
    DROP TABLE dbo.DefragmentIndexes_Old

EXEC sp_rename N'dbo.DefragmentIndexes', @ArchiveTableName, N'OBJECT';

DECLARE @indexes TABLE (LineID INT NOT NULL IDENTITY(1,1), index_name SYSNAME)

INSERT @indexes
    SELECT i.name
    FROM sys.indexes i
    WHERE i.object_id = OBJECT_ID(@ArchiveTableName)
        AND i.index_id <> 1

DECLARE @i INT, @index_name SYSNAME

SELECT TOP(1) @i = LineId, @index_name = index_name FROM @indexes

WHILE @i IS NOT NULL BEGIN
    EXEC('DROP INDEX ' + @ArchiveTableName + '.' + @index_name)
    DELETE @indexes WHERE LineID = @i
    SET @i = NULL
    SELECT TOP(1) @i = LineId, @index_name = index_name FROM @indexes
END

CreateTable:
CREATE TABLE DefragmentIndexes
(
    LineId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
    DatabaseName SYSNAME NOT NULL,
    SchemaName SYSNAME NOT NULL,
    TableName SYSNAME NOT NULL,
    IndexName SYSNAME NOT NULL,
    DefragmentDate datetime NOT NULL,
    PercentFragmented decimal(4, 2) NOT NULL,
)
GO
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'nci_DefragmentIndexes_DefragmentDate')
CREATE INDEX nci_DefragmentIndexes_DefragmentDate
    ON DefragmentIndexes (DefragmentDate)
    INCLUDE (SchemaName, TableName)
GO
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name= 'nci_DefragmentIndexes_TableName_SchemaName')
CREATE INDEX nci_DefragmentIndexes_TableName_SchemaName
    ON DefragmentIndexes (TableName, SchemaName)
    INCLUDE (DefragmentDate)


IF OBJECT_ID(N'[dbo].[isp_ALTER_INDEX]') IS NOT NULL
    DROP PROC [dbo].[isp_ALTER_INDEX]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROC [dbo].[isp_ALTER_INDEX]
    @dbName sysname,
    @statsMode varchar(8) = 'SAMPLED',
    @defragType varchar(10) = 'REORGANIZE',
    @minFragPercent int = 25,
    @maxFragPercent int = 100,
    @minRowCount int = 0,
    @logHistory bit = 0,
    @sortInTempdb bit = 0
AS BEGIN
    SET NOCOUNT ON

    IF @statsMode NOT IN ('LIMITED', 'SAMPLED', 'DETAILED') BEGIN
        RAISERROR('@statsMode must be LIMITED, SAMPLED or DETAILED', 16, 1)
        RETURN
    END

    IF @defragType NOT IN ('REORGANIZE', 'REBUILD') BEGIN
        RAISERROR('@defragType must be REORGANIZE or REBUILD', 16, 1)
        RETURN
    END

    DECLARE @i int, @objectId int, @objectName sysname, @indexId int, @indexName sysname,
            @schemaName sysname, @partitionNumber int, @partitionCount int, @sql nvarchar(4000), 
            @edition int, @parmDef nvarchar(500), @allocUnitType nvarchar(60), @indexType nvarchar(60), 
            @online bit, @disabled bit, @dataType nvarchar(128), @charMaxLen int, @allowPageLocks bit, 
            @lobData bit, @fragPercent float

    SELECT @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))

    SELECT IDENTITY(int, 1, 1) AS FragIndexId,
        [object_id] AS ObjectId,
        index_id AS IndexId,
        avg_fragmentation_in_percent AS FragPercent,
        record_count AS RecordCount,
        partition_number AS PartitionNumber,
        index_type_desc AS IndexType,
        alloc_unit_type_desc AS AllocUnitType
    INTO #FragIndex
    FROM sys.dm_db_index_physical_stats (DB_ID(@dbName), NULL, NULL, NULL, @statsMode)
    WHERE avg_fragmentation_in_percent > @minFragPercent AND
        avg_fragmentation_in_percent < @maxFragPercent AND
        index_id > 0 AND
        index_level = 0
    ORDER BY ObjectId

    IF @statsMode IN ('SAMPLED', 'DETAILED')
        DELETE FROM #FragIndex
        WHERE RecordCount < @minRowCount

    SELECT @i = MIN(FragIndexId)
    FROM #FragIndex

    SELECT @objectId = ObjectId,
        @indexId = IndexId,
        @fragPercent = FragPercent,
        @partitionNumber = PartitionNumber,
        @indexType = IndexType,
        @allocUnitType = AllocUnitType
    FROM #FragIndex
    WHERE FragIndexId = @i

    WHILE @@ROWCOUNT <> 0 BEGIN

        SET @sql = 'SELECT @objectName = o.[name], @schemaName = s.[name]
        FROM ' + QUOTENAME(@dbName) + '.sys.objects o
        JOIN ' + QUOTENAME(@dbName) + '.sys.schemas s
        ON s.schema_id = o.schema_id
        WHERE o.[object_id] = @objectId'

        SET @parmDef = N'@objectId int, @objectName sysname OUTPUT, @schemaName sysname OUTPUT'

        EXEC sp_executesql @sql, @parmDef, @objectId = @objectId, @objectName = @objectName OUTPUT, 
            @schemaName = @schemaName OUTPUT

        SET @sql = 'SELECT @indexName = [name], @disabled = is_disabled, @allowPageLocks = allow_page_locks
            FROM ' + QUOTENAME(@dbName) + '.sys.indexes
            WHERE [object_id] = @objectId AND index_id = @indexId'

        SET @parmDef = N'@objectId int, @indexId int, @indexName sysname OUTPUT, @disabled bit OUTPUT, @allowPageLocks bit OUTPUT'

        EXEC sp_executesql @sql, @parmDef, @objectId = @objectId, @indexId = @indexId, @indexName = @indexName OUTPUT, @disabled = @disabled OUTPUT,
            @allowPageLocks = @allowPageLocks OUTPUT

        SET @lobData = 0

        IF @indexType = 'CLUSTERED INDEX' BEGIN

            SET @sql = '
                SELECT @lobData = 1
                FROM ' + QUOTENAME(@dbName) + '.INFORMATION_SCHEMA.COLUMNS c
                WHERE TABLE_SCHEMA = @schemaName AND
                TABLE_NAME = @objectName AND
                (DATA_TYPE IN (''text'', ''ntext'', ''image'') OR
                CHARACTER_MAXIMUM_LENGTH = -1)'
            SET @parmDef = N'@schemaName sysname, @objectName sysname, @lobData bit OUTPUT'
            EXEC sp_executesql @sql, @parmDef, @schemaName = @schemaName, @objectName = @objectName, 
                @lobData = @lobData OUTPUT
        END
        ELSE IF @indexType = 'NONCLUSTERED INDEX'
        BEGIN
            SET @sql = 'SELECT @lobData = 1
                FROM ' + QUOTENAME(@dbName) + '.sys.indexes i
                JOIN ' + QUOTENAME(@dbName) + '.sys.index_columns ic
                        ON i.object_id = ic.object_id
                JOIN ' + QUOTENAME(@dbName) + '.INFORMATION_SCHEMA.COLUMNS c
                        ON ic.column_id = c.ORDINAL_POSITION
                WHERE c.TABLE_SCHEMA = @schemaName AND
                    c.TABLE_NAME = @objectName AND
                    i.name = @indexName AND
                    ic.is_included_column = 1 AND
                    (c.DATA_TYPE IN (''text'', ''ntext'', ''image'')
                    OR c.CHARACTER_MAXIMUM_LENGTH = -1)'

            SET @parmDef = N'@schemaName sysname, @objectName sysname, @indexName sysname, @lobData bit OUTPUT'

            EXEC sp_executesql @sql, @parmDef, @schemaName = @schemaName, @objectName = @objectName,
                @indexName = @indexName, @lobData = @lobData OUTPUT
        END

        SET @sql = 'SELECT @partitionCount = COUNT(*)
            FROM ' + QUOTENAME(@dbName) + '.sys.partitions
            WHERE [object_id] = @objectId AND index_id = @indexId'

        SET @parmDef = N'@objectId int, @indexId int, @partitionCount int OUTPUT'

        EXEC sp_executesql @sql, @parmDef, @objectId = @objectId, @indexId = @indexId, 
            @partitionCount = @partitionCount OUTPUT

        IF @edition = 3 AND (@defragType = 'REBUILD' OR (@defragType = 'REORGANIZE' AND @allowPageLocks = 0)) BEGIN
            SET @online = CASE  WHEN @indexType IN ('XML INDEX', 'PRIMARY XML INDEX') THEN 0
                                WHEN @indexType = 'NONCLUSTERED INDEX' AND @allocUnitType = 'LOB_DATA' THEN 0
                                WHEN @lobData = 1 THEN 0
                                WHEN @disabled = 1 THEN 0
                                WHEN @partitionCount > 1 THEN 0
                                ELSE 1
                            END
        END
        ELSE
            SET @online = 0

        SET @sql = 'ALTER INDEX ' + QUOTENAME(@indexName) + ' ON ' + QUOTENAME(@dbName) + '.' + 
                    QUOTENAME(@schemaName) + '.' + QUOTENAME(@objectName) +
                    CASE    WHEN @defragType = ' REORGANIZE' AND @allowPageLocks = 0 
                            THEN ' REBUILD'
                            ELSE ' ' + @defragType
                    END

        IF @online = 1 OR @sortInTempdb = 1 BEGIN
            SET @sql = @sql + ' WITH (' +
                    CASE    WHEN @online = 1 AND @sortInTempdb = 1 THEN 'ONLINE = ON, SORT_IN_TEMPDB = ON'
                            WHEN @online = 1 AND @sortInTempdb = 0 THEN 'ONLINE = ON'
                            WHEN @online = 0 AND @sortInTempdb = 1 THEN 'SORT_IN_TEMPDB = ON'
                    END + ')'
        END

        IF @partitionCount > 1 AND @disabled = 0 AND @indexType <> 'XML INDEX'
            SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS varchar(10))

        EXEC (@SQL)

        IF @logHistory = 1
            INSERT INTO DefragmentIndexes (DatabaseName, SchemaName, TableName, IndexName, DefragmentDate, PercentFragmented)
            VALUES(@dbName, @schemaName, @objectName, @indexName, GETDATE(), @fragPercent)

        SELECT @i = MIN(FragIndexId) 
        FROM #FragIndex 
        WHERE FragIndexId > @i

        SELECT @objectId = ObjectId, @indexId = IndexId, @fragPercent = FragPercent, @partitionNumber = PartitionNumber, 
                @indexType = IndexType, @allocUnitType = AllocUnitType
        FROM #FragIndex
        WHERE FragIndexId = @i
    END
END
GO
EXEC isp_ALTER_INDEX
@dbName = 'MODEV',
@statsMode = 'SAMPLED',
@defragType = 'REBUILD',
@minFragPercent = 1,
@maxFragPercent = 100,
@minRowCount = 10,
@logHistory = 1,
@sortInTempdb = 1
GO