Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
schinni
Yak Posting Veteran
66 Posts |
Posted - 2003-05-28 : 19:03:21
|
| Hello,This is from sqlbol,it's a good one and I wanted to make sp andcreate it in master database and use it for all databases--- create sp_test @dbname sysname as-- Declare variablesSET NOCOUNT ONDECLARE @tablename VARCHAR (128)DECLARE @execstr VARCHAR (255)DECLARE @objectid INTDECLARE @indexid INTDECLARE @frag DECIMALDECLARE @maxfrag DECIMAL-- Decide on the maximum fragmentation to allowSELECT @maxfrag = 30.0-- Declare cursorDECLARE tables CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'-- Create the tableCREATE TABLE #fraglist ( ObjectName CHAR (255), ObjectId INT, IndexName CHAR (255), IndexId INT, Lvl INT, CountPages INT, CountRows INT, MinRecSize INT, MaxRecSize INT, AvgRecSize INT, ForRecCount INT, Extents INT, ExtentSwitches INT, AvgFreeBytes INT, AvgPageDensity INT, ScanDensity DECIMAL, BestCount INT, ActualCount INT, LogicalFrag DECIMAL, ExtentFrag DECIMAL)-- Open the cursorOPEN tables-- Loop through all the tables in the databaseFETCH NEXT FROM tables INTO @tablenameWHILE @@FETCH_STATUS = 0BEGIN-- Do the showcontig of all indexes of the table INSERT INTO #fraglist EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS') FETCH NEXT FROM tables INTO @tablenameEND-- Close and deallocate the cursorCLOSE tablesDEALLOCATE tables-- Declare cursor for list of indexes to be defraggedDECLARE indexes CURSOR FOR SELECT ObjectName, ObjectId, IndexId, LogicalFrag FROM #fraglist WHERE LogicalFrag >= @maxfrag AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0-- Open the cursorOPEN indexes-- loop through the indexesFETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @fragWHILE @@FETCH_STATUS = 0BEGIN PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ', ' + RTRIM(@indexid) + ') - fragmentation currently ' + RTRIM(CONVERT(varchar(15),@frag)) + '%' SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ', ' + RTRIM(@indexid) + ')' EXEC (@execstr) FETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @fragEND-- Close and deallocate the cursorCLOSE indexesDEALLOCATE indexes-- Delete the temporary tableDROP TABLE #fraglistand execute assp_test 'Northwind'Thanks,Edited by - schinni on 05/29/2003 08:35:30 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-05-28 : 19:06:52
|
| Is there a question?Tara |
 |
|
|
SamC
White Water Yakist
3467 Posts |
Posted - 2003-05-28 : 19:23:55
|
|
 |
|
|
schinni
Yak Posting Veteran
66 Posts |
Posted - 2003-05-28 : 20:28:24
|
| the question is i couldn't create in the master databasei can create but it doesn't work for other databases on the machine.iwant to know how to modify the sp so that it works for all databaseson the machine |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-05-28 : 20:35:55
|
| What is the error that you got when you tried to create it in the master database? Does SQL Server Books Online give you any details about it? If you want us to help with this, you'll need to let us know how to find the stored procedure in BOL so that we can read the related information. We also need to know all of the errors that you are getting? Looking at the stored procedure, it appears that it isn't written correctly. It accepts @dbname as an input parameter but doesn't ever use @dbname for anything. All table names should be prefaced with @dbname probably otherwise you'll have to run this stored procedure in the user database.Try creating the stored procedure in Northwind (remove @dbname sysname from stored procedure though cuz it's not used anyway). Then run: EXEC sp_test...Does it work?Tara |
 |
|
|
schinni
Yak Posting Veteran
66 Posts |
Posted - 2003-05-28 : 20:42:23
|
| yes it works if i create sp_test in northwind databaseit is in sql2k bol for dbcc showcontigThanks, |
 |
|
|
schinni
Yak Posting Veteran
66 Posts |
Posted - 2003-05-28 : 22:14:42
|
quote: Hello,This is from sqlbol,it's a good one and I wanted to make sp andcreate it in master database and use it for all databases--- create sp_test @dbname sysname as-- Declare variablesSET NOCOUNT ONDECLARE @tablename VARCHAR (128)DECLARE @execstr VARCHAR (255)DECLARE @objectid INTDECLARE @indexid INTDECLARE @frag DECIMALDECLARE @maxfrag DECIMAL-- Decide on the maximum fragmentation to allowSELECT @maxfrag = 30.0-- Declare cursorDECLARE tables CURSOR FOR SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'-- Create the tableCREATE TABLE #fraglist ( ObjectName CHAR (255), ObjectId INT, IndexName CHAR (255), IndexId INT, Lvl INT, CountPages INT, CountRows INT, MinRecSize INT, MaxRecSize INT, AvgRecSize INT, ForRecCount INT, Extents INT, ExtentSwitches INT, AvgFreeBytes INT, AvgPageDensity INT, ScanDensity DECIMAL, BestCount INT, ActualCount INT, LogicalFrag DECIMAL, ExtentFrag DECIMAL)-- Open the cursorOPEN tables-- Loop through all the tables in the databaseFETCH NEXT FROM tables INTO @tablenameWHILE @@FETCH_STATUS = 0BEGIN-- Do the showcontig of all indexes of the table INSERT INTO #fraglist EXEC ('DBCC SHOWCONTIG (''' + @tablename + ''') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS') FETCH NEXT FROM tables INTO @tablenameEND-- Close and deallocate the cursorCLOSE tablesDEALLOCATE tables-- Declare cursor for list of indexes to be defraggedDECLARE indexes CURSOR FOR SELECT ObjectName, ObjectId, IndexId, LogicalFrag FROM #fraglist WHERE LogicalFrag >= @maxfrag AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0-- Open the cursorOPEN indexes-- loop through the indexesFETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @fragWHILE @@FETCH_STATUS = 0BEGIN PRINT 'Executing DBCC INDEXDEFRAG (0, ' + RTRIM(@tablename) + ', ' + RTRIM(@indexid) + ') - fragmentation currently ' + RTRIM(CONVERT(varchar(15),@frag)) + '%' SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ', ' + RTRIM(@indexid) + ')' EXEC (@execstr) FETCH NEXT FROM indexes INTO @tablename, @objectid, @indexid, @fragEND-- Close and deallocate the cursorCLOSE indexesDEALLOCATE indexes-- Delete the temporary tableDROP TABLE #fraglistand execute assp_test 'Northwind'Thanks,
|
 |
|
|
schinni
Yak Posting Veteran
66 Posts |
Posted - 2003-05-29 : 19:08:56
|
| hope the question is clearThanks, |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2003-05-29 : 20:01:55
|
| In order to be able to do this, DBCC SHOWCONTIG would have to allow the 3 part name for the table, such as DB1.dbo.Table1. The problem is that DBCC SHOWCONTIG only allows the 2 part name, such as [dbo.Table1] and yes the brackets are required, or the 1 part name, such as Table1. Since you can not do a USE statement in the stored procedure, you can not switch databases so that it runs in each of the databases. So I believe that the answer is that you will have to create this stored procedure in each of your user databases and run it in each of your user databases. Maybe someone here can prove me wrong, but I just don't think that this is possible in a stored procedure.Tara |
 |
|
|
jason
Posting Yak Master
164 Posts |
Posted - 2005-04-18 : 12:26:49
|
Hi,I decided to implement this too and ran into the same issue. I've modified the BOL SQL posted below so that it should address each table by owner name. I tried to highlight changes I made for easier reading.Anyone see any problem with it? Comments, suggestions, recommendations appreciated.Use MyDB-- Declare variablesSET NOCOUNT ONDECLARE @tablename VARCHAR (128)DECLARE @ownername VARCHAR (128)DECLARE @fullname VARCHAR (255)DECLARE @execstr VARCHAR (255)DECLARE @objectid INTDECLARE @indexid INTDECLARE @frag DECIMALDECLARE @maxfrag DECIMAL-- Decide on the maximum fragmentation to allowSELECT @maxfrag = 30.0-- Declare cursorDECLARE tables CURSOR FOR SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'-- Create the tableCREATE TABLE #fraglist ( ObjectName CHAR (255), ObjectId INT, IndexName CHAR (255), IndexId INT, Lvl INT, CountPages INT, CountRows INT, MinRecSize INT, MaxRecSize INT, AvgRecSize INT, ForRecCount INT, Extents INT, ExtentSwitches INT, AvgFreeBytes INT, AvgPageDensity INT, ScanDensity DECIMAL, BestCount INT, ActualCount INT, LogicalFrag DECIMAL, ExtentFrag DECIMAL)CREATE TABLE #fraglink ( ObjectName CHAR (255), ObjectOwner CHAR (255))-- Open the cursorOPEN tables-- Loop through all the tables in the databaseFETCH NEXT FROM tables INTO @tablename, @ownernameWHILE @@FETCH_STATUS = 0BEGIN-- Do the showcontig of all indexes of the table SET @fullname = @ownername + '.' + @tablename INSERT INTO #fraglist EXEC ('DBCC SHOWCONTIG (''' + @fullname + ''') WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS') INSERT #fraglink (ObjectName,ObjectOwner) VALUES (@tablename,@ownername) FETCH NEXT FROM tables INTO @tablename, @ownernameEND-- Close and deallocate the cursorCLOSE tablesDEALLOCATE tables-- Declare cursor for list of indexes to be defraggedDECLARE indexes CURSOR FOR SELECT #fraglink.ObjectOwner AS ObjectOwner, #fraglist.ObjectName AS ObjectName, #fraglist.ObjectId AS ObjectId, #fraglist.IndexId AS IndexId, #fraglist.LogicalFrag AS LogicalFrag FROM #fraglink INNER JOIN #fraglist ON #fraglink.ObjectName = #fraglist.ObjectName WHERE #fraglist.LogicalFrag >= @maxfrag AND INDEXPROPERTY (#fraglist.ObjectId, #fraglist.IndexName, 'IndexDepth') > 0-- Open the cursorOPEN indexes-- loop through the indexesFETCH NEXT FROM indexes INTO @ownername, @tablename, @objectid, @indexid, @fragWHILE @@FETCH_STATUS = 0BEGIN SET @fullname = RTRIM(@ownername) + '.' + RTRIM(@tablename) PRINT 'Executing DBCC INDEXDEFRAG (0, ' + @fullname + ', ' + RTRIM(@indexid) + ') - fragmentation currently ' + RTRIM(CONVERT(varchar(15),@frag)) + '%' SELECT @execstr = 'DBCC INDEXDEFRAG (0, ' + RTRIM(@objectid) + ', ' + RTRIM(@indexid) + ')' EXEC (@execstr) FETCH NEXT FROM indexes INTO @ownername, @tablename, @objectid, @indexid, @fragEND-- Close and deallocate the cursorCLOSE indexesDEALLOCATE indexes-- Delete the temporary tableDROP TABLE #fraglistDROP TABLE #fraglinkGO |
 |
|
|
jason
Posting Yak Master
164 Posts |
Posted - 2005-04-18 : 13:22:48
|
| BTW, this works in testing, I'm looking for comments on efficiency, performance, etc. |
 |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2005-04-18 : 13:54:23
|
You can run DBCC SHOWCONTIG against another database, but you have to do it inside an EXECUTE statement and have a USE database command before the DBCC SHOWCONTIG.use tempdbexec ('--Switch to pubs databaseuse pubsDBCC SHOWCONTIG ( authors )')CODO ERGO SUM |
 |
|
|
jason
Posting Yak Master
164 Posts |
Posted - 2005-04-18 : 17:16:16
|
| Actually, I intend to call this as stored procedure. Something like:sp_defragdb 'MyDB'That way I can call it upon conditional outcomes of other maintenance items.1) Full backup of DB --> Continue on success, quit and report failure2) Remove files committed to tape --> Continue on success/failure3) Check DB health --> Continue on success, quit and report failure4) Defrag Indexes --> Quit on success, quit and report failure |
 |
|
|
|
|
|
|
|