This really needs to be modified to eliminate the system DBs but I don't have time right now to add it:
EXEC sp_MSForEachDB 'Use ?; exec sp_changedbowner sa'
EXEC sp_MSForEachDB 'ALTER DATABASE ? SET RECOVERY SIMPLE;'
EXEC sp_MSForEachDB 'ALTER DATABASE ? SET COMPATIBILITY_LEVEL = 110;'
EXEC sp_MSForEachDB 'Use ?; CREATE USER [DOMAIN\User_or_Group] WITH DEFAULT_SCHEMA = dbo;'
EXEC sp_MSForEachDB 'Use ?; ALTER ROLE db_owner ADD MEMBER [DOMAIN\User_or_Group];'
This is my collection of mostly useful SQL server information that helps administer the server. It is mostly aimed at SQL Server 2012 / 2014 / 2016.
Showing posts with label sql_maintenance. Show all posts
Showing posts with label sql_maintenance. Show all posts
Tuesday, December 16, 2014
Wednesday, June 20, 2012
Update to handle snapshots and not try to back them up in any multi-database queries
SELECT DISTINCT
s_mf.database_id
, *
FROM sys.master_files s_mf
INNER JOIN sys.databases s_db
ON s_mf.database_id = s_db.database_id
WHERE s_mf.state = 0 -- Online
AND s_db.source_database_id is null --Eliminate All Snapshots
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND NOT db_name(s_mf.database_id) in ('tempdb', 'master', 'msdb', 'model') --eliminate temp db
SELECT DISTINCT
s_mf.database_id
, *
FROM sys.master_files s_mf
INNER JOIN sys.databases s_db
ON s_mf.database_id = s_db.database_id
WHERE s_mf.state = 0 -- Online
AND s_db.source_database_id is null --Eliminate All Snapshots
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND NOT db_name(s_mf.database_id) in ('tempdb', 'master', 'msdb', 'model') --eliminate temp db
Tuesday, January 13, 2009
SQL Check DB
/*
This is the routine I use for running check DB. It simply loops through the master miles and runs check DB. There is an optional parameter to suppress info messages.
*/
USE [master]
GO
DECLARE @tDatabases TABLE
( databaseId int
);
INSERT INTO @tDatabases ( databaseId )
SELECT DISTINCT s_mf.database_id
FROM sys.databases s_mf
WHERE s_mf.state = 0 -- ONLINE
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND NOT [NAME] IN ('tempdb', 'master', 'model', 'msdb' )--eliminate temp db
;
DECLARE cursor_usage CURSOR FOR SELECT databaseId FROM @tDatabases;
DECLARE @dbId INT;
OPEN cursor_usage;
FETCH NEXT FROM cursor_usage INTO @dbId;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT db_name(@dbId);
DECLARE @dbname nvarchar(50)
SET @dbname = db_name(@dbId);
DBCC CHECKDB (@dbName);
FETCH NEXT FROM cursor_usage INTO @dbId;
END;
CLOSE cursor_usage;
DEALLOCATE cursor_usage;
This is the routine I use for running check DB. It simply loops through the master miles and runs check DB. There is an optional parameter to suppress info messages.
*/
USE [master]
GO
DECLARE @tDatabases TABLE
( databaseId int
);
INSERT INTO @tDatabases ( databaseId )
SELECT DISTINCT s_mf.database_id
FROM sys.databases s_mf
WHERE s_mf.state = 0 -- ONLINE
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND NOT [NAME] IN ('tempdb', 'master', 'model', 'msdb' )--eliminate temp db
;
DECLARE cursor_usage CURSOR FOR SELECT databaseId FROM @tDatabases;
DECLARE @dbId INT;
OPEN cursor_usage;
FETCH NEXT FROM cursor_usage INTO @dbId;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT db_name(@dbId);
DECLARE @dbname nvarchar(50)
SET @dbname = db_name(@dbId);
DBCC CHECKDB (@dbName);
FETCH NEXT FROM cursor_usage INTO @dbId;
END;
CLOSE cursor_usage;
DEALLOCATE cursor_usage;
Wednesday, November 12, 2008
Improved SQL Index Update Script
I have modified this script to be compatible with the Share Point server database I am now supporting. This script replaces the previous one completely. This is used in conjunction with a script that feeds the database information for every database to it. I normally place it in master so I do not have to add it to every database.
--:2008 - 06- 06 Updated to run online and offline
--:2008-11-12 Added Share Point support
--:2009-01-13 Added a trimmer to make sure the database name is good
-- INPUTS : @dbName - name of the database
-- @statsMode - mode to use for sys.dm_db_index_physical_stats
-- @defragType - REORGANIZE (INDEXDEFRAG) or REBUILD (DBREINDEX)
-- @minFragPercent - minimum fragmentation level
-- @maxFragPercent - maximum fragmentation level
-- @minRowCount - minimum row count
-- @PerformOnlineOnly - Forces to rebuild to be online for enterprise ed. without 1 = true
--
-- OUTPUTS : None
--
-- DEPENDENCIES : sys.dm_db_index_physical_stats, sys.objects,
-- sys.schemas, sys.indexes, sys.partitions
--
-- DESCRIPTION : Defragments indexes
/*
EXEC DbUtil_ALTER_INDEX
@dbName = 'DatabaseName',
@statsMode = 'SAMPLED',
@defragType = 'REBUILD',
@minFragPercent = 10,
@maxFragPercent = 100,
@minRowCount = 1000
, @PerformOnlineOnly = 1
*/
-------------------------------------------------------------------------------------------
CREATE PROC [dbo].[DbUtil_ALTER_INDEX]
(
@dbName sysname
, @statsMode varchar(8) = 'SAMPLED'
, @defragType varchar(10) = 'REORGANIZE'
, @minFragPercent int = 25
, @maxFragPercent int = 100
, @minRowCount int = 0
, @PerformOnlineOnly bit = 1
)
AS
SET NOCOUNT ON
DECLARE @i int
DECLARE @objectId int
DECLARE @objectName sysname
DECLARE @indexId int
DECLARE @indexName sysname
DECLARE @schemaName sysname
DECLARE @partitionNumber int
DECLARE @partitionCount int
DECLARE @recordCount bigint
DECLARE @sql nvarchar(4000)
DECLARE @edition int
DECLARE @parmDef nvarchar(500)
SELECT @i = 1, @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
--Make sure the temp table does not exist
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
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 PartitionNumberINTO #FragIndexFROM sys.dm_db_index_physical_stats (DB_ID(@dbName), NULL, NULL, NULL, @statsMode)WHERE avg_fragmentation_in_percent > @minFragPercentAND avg_fragmentation_in_percent < @maxFragPercent AND index_id > 0AND record_count > @minRowCountORDER BY ObjectId
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCountFROM #FragIndexWHERE FragIndexId = @i
--Make sure that the DB name is trimmed otherwise the procedure will failSELECT @dbName = LTRIM(RTRIM(@dbName))
USE [master]
GO/****** Object: StoredProcedure [dbo].[DbUtil_ALTER_INDEX] Script Date: 06/05/2008 16:18:35 ******/
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GO-------------------------------------------------------------------------------------------
-- OBJECT NAME : DbUtil_ALTER_INDEX
-- AUTHOR: Alan T
-- BASED ON A SCRIPT: Tara Kizer
---- DATE : February 27, 2007GO/****** Object: StoredProcedure [dbo].[DbUtil_ALTER_INDEX] Script Date: 06/05/2008 16:18:35 ******/
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GO-------------------------------------------------------------------------------------------
-- OBJECT NAME : DbUtil_ALTER_INDEX
-- AUTHOR: Alan T
-- BASED ON A SCRIPT: Tara Kizer
--:2008 - 06- 06 Updated to run online and offline
--:2008-11-12 Added Share Point support
--:2009-01-13 Added a trimmer to make sure the database name is good
-- INPUTS : @dbName - name of the database
-- @statsMode - mode to use for sys.dm_db_index_physical_stats
-- @defragType - REORGANIZE (INDEXDEFRAG) or REBUILD (DBREINDEX)
-- @minFragPercent - minimum fragmentation level
-- @maxFragPercent - maximum fragmentation level
-- @minRowCount - minimum row count
-- @PerformOnlineOnly - Forces to rebuild to be online for enterprise ed. without 1 = true
--
-- OUTPUTS : None
--
-- DEPENDENCIES : sys.dm_db_index_physical_stats, sys.objects,
-- sys.schemas, sys.indexes, sys.partitions
--
-- DESCRIPTION : Defragments indexes
/*
EXEC DbUtil_ALTER_INDEX
@dbName = 'DatabaseName',
@statsMode = 'SAMPLED',
@defragType = 'REBUILD',
@minFragPercent = 10,
@maxFragPercent = 100,
@minRowCount = 1000
, @PerformOnlineOnly = 1
*/
-------------------------------------------------------------------------------------------
CREATE PROC [dbo].[DbUtil_ALTER_INDEX]
(
@dbName sysname
, @statsMode varchar(8) = 'SAMPLED'
, @defragType varchar(10) = 'REORGANIZE'
, @minFragPercent int = 25
, @maxFragPercent int = 100
, @minRowCount int = 0
, @PerformOnlineOnly bit = 1
)
AS
SET NOCOUNT ON
DECLARE @i int
DECLARE @objectId int
DECLARE @objectName sysname
DECLARE @indexId int
DECLARE @indexName sysname
DECLARE @schemaName sysname
DECLARE @partitionNumber int
DECLARE @partitionCount int
DECLARE @recordCount bigint
DECLARE @sql nvarchar(4000)
DECLARE @edition int
DECLARE @parmDef nvarchar(500)
SELECT @i = 1, @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
--Make sure the temp table does not exist
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
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 PartitionNumberINTO #FragIndexFROM sys.dm_db_index_physical_stats (DB_ID(@dbName), NULL, NULL, NULL, @statsMode)WHERE avg_fragmentation_in_percent > @minFragPercentAND avg_fragmentation_in_percent < @maxFragPercent AND index_id > 0AND record_count > @minRowCountORDER BY ObjectId
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCountFROM #FragIndexWHERE FragIndexId = @i
WHILE @@ROWCOUNT <> 0
BEGIN
SET @sql = '
SELECT @objectName = o.[name], @schemaName = s.[name]
FROM [' + @dbName + '].sys.objects o
JOIN [' + @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]
FROM [' + @dbName + '].sys.indexes
WHERE [object_id] = @objectId AND index_id = @indexId AND is_disabled = 0'
SET @parmDef = N'@objectId int, @indexId int, @indexName sysname OUTPUT'
EXEC sp_executesql
@sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
@indexName = @indexName OUTPUT
SET @sql = 'SELECT @partitionCount = COUNT(*)
FROM [' + @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
SET @sql = 'ALTER INDEX [' + @indexName + '] ON [' + @dbName + '].[' +
@schemaName + '].[' + @objectName + '] ' + @defragType
-- Developer and Enterprise have the ONLINE = ON option for REBUILD
IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 1 SET @sql = @sql + ' WITH (ONLINE = ON)'
ELSE IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 0 SET @sql = @sql + ' WITH (ONLINE = OFF)'
IF @partitionCount > 1 SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS varchar(10))
print @sql
BEGIN TRY
EXEC (@SQL)
END TRY
BEGIN CATCH
print 'ERROR1 : ' + cast(ERROR_LINE() as nvarchar(10)); print 'ERROR2 : ' + ERROR_MESSAGE();
BEGIN
SET @sql = '
SELECT @objectName = o.[name], @schemaName = s.[name]
FROM [' + @dbName + '].sys.objects o
JOIN [' + @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]
FROM [' + @dbName + '].sys.indexes
WHERE [object_id] = @objectId AND index_id = @indexId AND is_disabled = 0'
SET @parmDef = N'@objectId int, @indexId int, @indexName sysname OUTPUT'
EXEC sp_executesql
@sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
@indexName = @indexName OUTPUT
SET @sql = 'SELECT @partitionCount = COUNT(*)
FROM [' + @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
SET @sql = 'ALTER INDEX [' + @indexName + '] ON [' + @dbName + '].[' +
@schemaName + '].[' + @objectName + '] ' + @defragType
-- Developer and Enterprise have the ONLINE = ON option for REBUILD
IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 1 SET @sql = @sql + ' WITH (ONLINE = ON)'
ELSE IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 0 SET @sql = @sql + ' WITH (ONLINE = OFF)'
IF @partitionCount > 1 SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS varchar(10))
print @sql
BEGIN TRY
EXEC (@SQL)
END TRY
BEGIN CATCH
print 'ERROR1 : ' + cast(ERROR_LINE() as nvarchar(10)); print 'ERROR2 : ' + ERROR_MESSAGE();
RETURN -1;END CATCH;
SET @i = @i + 1
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCountFROM #FragIndexWHERE FragIndexId = @iEND
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
return 0;
SET @i = @i + 1
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCountFROM #FragIndexWHERE FragIndexId = @iEND
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
return 0;
Monday, June 16, 2008
SQL Purge old database backups
/*
This script works with SQL 2005 to remove old backups from a file location
xp_delete_file
is the key to this operation. This is an undocumented SQL server function.
It deletes all file older than the date given in the parameter.
I use this to implement 24 hour disk to disk backup
The TSQL assumes the full backups have an extension of BAK and transaction logs
have an extension of TRN. It will purge both transaction logs and full backups
*/
USE [master]
GO
DECLARE @tDatabases TABLE
( databaseId int
--, DATABASE_NAME varchar(25)
)
INSERT INTO @tDatabases ( databaseId )
SELECT DISTINCT s_mf.database_id
from sys.master_files s_mf
where s_mf.state = 0 -- ONLINE
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND s_mf.database_id <> 2 --eliminate temp db
DECLARE @dbId int;
Declare @DateToDelete datetime;
declare @DateString char(8);
DECLARE @filePath nvarchar(max);
SET @DateToDelete=DateAdd(day,-1,GetDate()); --The -1 in the date diff is 24 hours
set @DateString = Convert(nvarchar(30),@DateToDelete,1)+' '+ Convert(nvarchar(30),@DateToDelete,8); --Set up SQL string
SET @filePath = '\server_backup_directory' ;
DECLARE cursor_usage CURSOR FOR
SELECT databaseId FROM @tDatabases;
OPEN cursor_usage;
FETCH NEXT FROM cursor_usage INTO @dbId;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT db_name(@dbId);
DECLARE @execString nvarchar(max)
--Remove full backups
SET @execString = 'master.dbo.xp_delete_file 0, N''' + @filePath + db_name(@dbId) + '''' +',N''bak'' ,' + '''' + @DateString + ''''
PRINT @execString;
EXECUTE (@execString);
--Remove transaction logs
SET @execString = 'master.dbo.xp_delete_file 0, N''' + @filePath + db_name(@dbId) + '''' +',N''trn'' ,' + '''' + @DateString + ''''
PRINT @execString;
EXECUTE (@execString);
FETCH NEXT FROM cursor_usage INTO @dbId;
END;
CLOSE cursor_usage;
DEALLOCATE cursor_usage;
This script works with SQL 2005 to remove old backups from a file location
xp_delete_file
is the key to this operation. This is an undocumented SQL server function.
It deletes all file older than the date given in the parameter.
I use this to implement 24 hour disk to disk backup
The TSQL assumes the full backups have an extension of BAK and transaction logs
have an extension of TRN. It will purge both transaction logs and full backups
*/
USE [master]
GO
DECLARE @tDatabases TABLE
( databaseId int
--, DATABASE_NAME varchar(25)
)
INSERT INTO @tDatabases ( databaseId )
SELECT DISTINCT s_mf.database_id
from sys.master_files s_mf
where s_mf.state = 0 -- ONLINE
AND has_dbaccess(db_name(s_mf.database_id)) = 1 -- Only look at databases to which we have access
AND s_mf.database_id <> 2 --eliminate temp db
DECLARE @dbId int;
Declare @DateToDelete datetime;
declare @DateString char(8);
DECLARE @filePath nvarchar(max);
SET @DateToDelete=DateAdd(day,-1,GetDate()); --The -1 in the date diff is 24 hours
set @DateString = Convert(nvarchar(30),@DateToDelete,1)+' '+ Convert(nvarchar(30),@DateToDelete,8); --Set up SQL string
SET @filePath = '\server_backup_directory' ;
DECLARE cursor_usage CURSOR FOR
SELECT databaseId FROM @tDatabases;
OPEN cursor_usage;
FETCH NEXT FROM cursor_usage INTO @dbId;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT db_name(@dbId);
DECLARE @execString nvarchar(max)
--Remove full backups
SET @execString = 'master.dbo.xp_delete_file 0, N''' + @filePath + db_name(@dbId) + '''' +',N''bak'' ,' + '''' + @DateString + ''''
PRINT @execString;
EXECUTE (@execString);
--Remove transaction logs
SET @execString = 'master.dbo.xp_delete_file 0, N''' + @filePath + db_name(@dbId) + '''' +',N''trn'' ,' + '''' + @DateString + ''''
PRINT @execString;
EXECUTE (@execString);
FETCH NEXT FROM cursor_usage INTO @dbId;
END;
CLOSE cursor_usage;
DEALLOCATE cursor_usage;
Thursday, June 12, 2008
Reindex Stored Procedure
USE [master]
GO
/****** Object: StoredProcedure [dbo].[DbUtil_ALTER_INDEX] Script Date: 06/05/2008 16:18:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-------------------------------------------------------------------------------------------
-- OBJECT NAME : DbUtil_ALTER_INDEX
--
-- AUTHOR : Tara Kizer
-- : Alan T
--
-- DATE : February 27, 2007
-- : 2008 - 06- 06
--
-- INPUTS : @dbName - name of the database
-- @statsMode - mode to use for sys.dm_db_index_physical_stats
-- @defragType - REORGANIZE (INDEXDEFRAG) or REBUILD (DBREINDEX)
-- @minFragPercent - minimum fragmentation level
-- @maxFragPercent - maximum fragmentation level
-- @minRowCount - minimum row count
-- @PerformOnlineOnly - Forces to rebuild to be online for enterprise ed. without 1 = true
--
-- OUTPUTS : None
--
-- DEPENDENCIES : sys.dm_db_index_physical_stats, sys.objects,
-- sys.schemas, sys.indexes, sys.partitions
--
-- DESCRIPTION : Defragments indexes
/*
EXEC DbUtil_ALTER_INDEX
@dbName = 'DatabaseName',
@statsMode = 'SAMPLED',
@defragType = 'REBUILD',
@minFragPercent = 10,
@maxFragPercent = 100,
@minRowCount = 1000
, @PerformOnlineOnly = 1
*/
-------------------------------------------------------------------------------------------
CREATE PROC [dbo].[DbUtil_ALTER_INDEX]
(
@dbName sysname
, @statsMode varchar(8) = 'SAMPLED'
, @defragType varchar(10) = 'REORGANIZE'
, @minFragPercent int = 25
, @maxFragPercent int = 100
, @minRowCount int = 0
, @PerformOnlineOnly bit = 1
)
AS
SET NOCOUNT ON
DECLARE @i int
DECLARE @objectId int
DECLARE @objectName sysname
DECLARE @indexId int
DECLARE @indexName sysname
DECLARE @schemaName sysname
DECLARE @partitionNumber int
DECLARE @partitionCount int
DECLARE @recordCount bigint
DECLARE @sql nvarchar(4000)
DECLARE @edition int
DECLARE @parmDef nvarchar(500)
SELECT @i = 1, @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
--Make sure the temp table does not exist
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
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
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 record_count > @minRowCount
ORDER BY ObjectId
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCount
FROM #FragIndex
WHERE FragIndexId = @i
WHILE @@ROWCOUNT <> 0
BEGIN
SET @sql = '
SELECT @objectName = o.[name], @schemaName = s.[name]
FROM ' + @dbName + '.sys.objects o
JOIN ' + @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]
FROM ' + @dbName + '.sys.indexes
WHERE [object_id] = @objectId AND index_id = @indexId AND is_disabled = 0'
SET @parmDef = N'@objectId int, @indexId int, @indexName sysname OUTPUT'
EXEC sp_executesql
@sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
@indexName = @indexName OUTPUT
SET @sql = 'SELECT @partitionCount = COUNT(*)
FROM ' + @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
SET @sql = 'ALTER INDEX [' + @indexName + '] ON [' + @dbName + '].[' +
@schemaName + '].[' + @objectName + '] ' + @defragType
-- Developer and Enterprise have the ONLINE = ON option for REBUILD
IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 1
SET @sql = @sql + ' WITH (ONLINE = ON)'
ELSE IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 0
SET @sql = @sql + ' WITH (ONLINE = OFF)'
IF @partitionCount > 1
SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS varchar(10))
print @sql
BEGIN TRY
EXEC (@SQL)
END TRY
BEGIN CATCH
print 'ERROR1 : ' + cast(ERROR_LINE() as nvarchar(10));
print 'ERROR2 : ' + ERROR_MESSAGE();
END CATCH;
SET @i = @i + 1
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCount
FROM #FragIndex
WHERE FragIndexId = @i
END
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
GO
/****** Object: StoredProcedure [dbo].[DbUtil_ALTER_INDEX] Script Date: 06/05/2008 16:18:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-------------------------------------------------------------------------------------------
-- OBJECT NAME : DbUtil_ALTER_INDEX
--
-- AUTHOR : Tara Kizer
-- : Alan T
--
-- DATE : February 27, 2007
-- : 2008 - 06- 06
--
-- INPUTS : @dbName - name of the database
-- @statsMode - mode to use for sys.dm_db_index_physical_stats
-- @defragType - REORGANIZE (INDEXDEFRAG) or REBUILD (DBREINDEX)
-- @minFragPercent - minimum fragmentation level
-- @maxFragPercent - maximum fragmentation level
-- @minRowCount - minimum row count
-- @PerformOnlineOnly - Forces to rebuild to be online for enterprise ed. without 1 = true
--
-- OUTPUTS : None
--
-- DEPENDENCIES : sys.dm_db_index_physical_stats, sys.objects,
-- sys.schemas, sys.indexes, sys.partitions
--
-- DESCRIPTION : Defragments indexes
/*
EXEC DbUtil_ALTER_INDEX
@dbName = 'DatabaseName',
@statsMode = 'SAMPLED',
@defragType = 'REBUILD',
@minFragPercent = 10,
@maxFragPercent = 100,
@minRowCount = 1000
, @PerformOnlineOnly = 1
*/
-------------------------------------------------------------------------------------------
CREATE PROC [dbo].[DbUtil_ALTER_INDEX]
(
@dbName sysname
, @statsMode varchar(8) = 'SAMPLED'
, @defragType varchar(10) = 'REORGANIZE'
, @minFragPercent int = 25
, @maxFragPercent int = 100
, @minRowCount int = 0
, @PerformOnlineOnly bit = 1
)
AS
SET NOCOUNT ON
DECLARE @i int
DECLARE @objectId int
DECLARE @objectName sysname
DECLARE @indexId int
DECLARE @indexName sysname
DECLARE @schemaName sysname
DECLARE @partitionNumber int
DECLARE @partitionCount int
DECLARE @recordCount bigint
DECLARE @sql nvarchar(4000)
DECLARE @edition int
DECLARE @parmDef nvarchar(500)
SELECT @i = 1, @edition = CONVERT(int, SERVERPROPERTY('EngineEdition'))
--Make sure the temp table does not exist
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
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
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 record_count > @minRowCount
ORDER BY ObjectId
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCount
FROM #FragIndex
WHERE FragIndexId = @i
WHILE @@ROWCOUNT <> 0
BEGIN
SET @sql = '
SELECT @objectName = o.[name], @schemaName = s.[name]
FROM ' + @dbName + '.sys.objects o
JOIN ' + @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]
FROM ' + @dbName + '.sys.indexes
WHERE [object_id] = @objectId AND index_id = @indexId AND is_disabled = 0'
SET @parmDef = N'@objectId int, @indexId int, @indexName sysname OUTPUT'
EXEC sp_executesql
@sql, @parmDef, @objectId = @objectId, @indexId = @indexId,
@indexName = @indexName OUTPUT
SET @sql = 'SELECT @partitionCount = COUNT(*)
FROM ' + @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
SET @sql = 'ALTER INDEX [' + @indexName + '] ON [' + @dbName + '].[' +
@schemaName + '].[' + @objectName + '] ' + @defragType
-- Developer and Enterprise have the ONLINE = ON option for REBUILD
IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 1
SET @sql = @sql + ' WITH (ONLINE = ON)'
ELSE IF @defragType = 'REBUILD' AND @edition = 3 AND @PerformOnlineOnly = 0
SET @sql = @sql + ' WITH (ONLINE = OFF)'
IF @partitionCount > 1
SET @sql = @sql + ' PARTITION = ' + CAST(@partitionNumber AS varchar(10))
print @sql
BEGIN TRY
EXEC (@SQL)
END TRY
BEGIN CATCH
print 'ERROR1 : ' + cast(ERROR_LINE() as nvarchar(10));
print 'ERROR2 : ' + ERROR_MESSAGE();
END CATCH;
SET @i = @i + 1
SELECT
@objectId = ObjectId,
@indexId = IndexId,
@recordCount = RecordCount
FROM #FragIndex
WHERE FragIndexId = @i
END
IF EXISTS(SELECT name FROM tempdb.dbo.sysobjects WHERE type = N'U' AND name like N'#FragIndex%') DROP TABLE #FragIndex;
Subscribe to:
Posts (Atom)