我正在尝试在存储过程下面运行,但是如果失败并出现以下错误
受影响的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
答案 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