2015-08-08 27 views
1

我目前使用Microsoft SQL腳本來碎片整理臨界值以上的索引,代碼和鏈接低於defrag。當我簡單地執行代碼時,這工作正常,但現在我想創建一個存儲過程和一個作業來自動執行任務。我的問題是,代碼需要在開始時有'USE',這在SP中是不可能的。我如何修改腳本來克服這個問題?過程中不允許使用USE數據庫

USE mydbname 

-- Declare variables 
SET NOCOUNT ON; 
DECLARE @tablename varchar(255); 
DECLARE @execstr varchar(400); 
DECLARE @objectid int; 
DECLARE @indexid int; 
DECLARE @frag  decimal; 
DECLARE @maxfrag decimal; 

-- Decide on the maximum fragmentation to allow for. 
SELECT @maxfrag = 30.0; 

-- Declare a cursor. 
DECLARE tables CURSOR FOR 
    SELECT TABLE_SCHEMA + '.' + TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE'; 

-- Create the table. 
CREATE 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 cursor. 
OPEN tables; 

-- Loop through all the tables in the database. 
FETCH NEXT 
    FROM tables 
    INTO @tablename; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
-- 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 @tablename; 
END; 

-- Close and deallocate the cursor. 
CLOSE tables; 
DEALLOCATE tables; 

-- Declare the cursor for the list of indexes to be defragged. 
DECLARE indexes CURSOR FOR 
    SELECT ObjectName, ObjectId, IndexId, LogicalFrag 
    FROM #fraglist 
    WHERE LogicalFrag >= @maxfrag 
     AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0; 

-- Open the cursor. 
OPEN indexes; 

-- Loop through the indexes. 
FETCH NEXT 
    FROM indexes 
    INTO @tablename, @objectid, @indexid, @frag; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    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, @frag; 
END; 

-- Close and deallocate the cursor. 
CLOSE indexes; 
DEALLOCATE indexes; 

-- Delete the temporary table. 
DROP TABLE #fraglist; 
GO 
+1

你有多少個數據庫?只需在每個數據庫中創建SP。沒有使用必要的聲明。 – Jeremy

回答

0

USE是SSMS命令,而不是SQL命令。您可以在頂部使用USE語句,然後使用GO對其進行分隔,然後創建過程。這將在所需數據庫的上下文中創建存儲過程。如果您需要多個數據庫中的sproc,只需更改頂部的USE語句,然後根據需要爲每個數據庫運行多次。

USE mydbname 

GO 
Create Procedure DefragDB AS Begin 
-- Declare variables 
SET NOCOUNT ON; 
DECLARE @tablename varchar(255); 
DECLARE @execstr varchar(400); 
DECLARE @objectid int; 
DECLARE @indexid int; 
DECLARE @frag  decimal; 
DECLARE @maxfrag decimal; 

-- Decide on the maximum fragmentation to allow for. 
SELECT @maxfrag = 30.0; 

-- Declare a cursor. 
DECLARE tables CURSOR FOR 
    SELECT TABLE_SCHEMA + '.' + TABLE_NAME 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE'; 

-- Create the table. 
CREATE 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 cursor. 
OPEN tables; 

-- Loop through all the tables in the database. 
FETCH NEXT 
    FROM tables 
    INTO @tablename; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
-- 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 @tablename; 
END; 

-- Close and deallocate the cursor. 
CLOSE tables; 
DEALLOCATE tables; 

-- Declare the cursor for the list of indexes to be defragged. 
DECLARE indexes CURSOR FOR 
    SELECT ObjectName, ObjectId, IndexId, LogicalFrag 
    FROM #fraglist 
    WHERE LogicalFrag >= @maxfrag 
     AND INDEXPROPERTY (ObjectId, IndexName, 'IndexDepth') > 0; 

-- Open the cursor. 
OPEN indexes; 

-- Loop through the indexes. 
FETCH NEXT 
    FROM indexes 
    INTO @tablename, @objectid, @indexid, @frag; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    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, @frag; 
END; 

-- Close and deallocate the cursor. 
CLOSE indexes; 
DEALLOCATE indexes; 

-- Delete the temporary table. 
DROP TABLE #fraglist; 
END