我想運行一個SQL腳本,它將在我的每個數據庫上創建一個函數,然後使用該函數填充一個臨時表,然後將其用作源另一個用於重建索引的遊標。然而,我遇到的問題是該函數只能在我當前連接的數據庫上創建,即使我正在使用我的光標中的「使用數據庫」。我已經複製了下面的腳本,這是爲了隔離問題而寫的(所以它還沒有效率)。反對所有數據庫中執行腳本SQL:在光標內部創建內聯表函數
IF OBJECT_ID (N'sp_index_maintenance', N'P') IS NOT NULL
DROP Proc sp_index_maintenance;
GO
Create proc sp_index_maintenance
AS
BEGIN
CREATE TABLE #T1
(
Database_Name NVARCHAR(MAX),
[Object_Name] NVARCHAR(MAX),
Index_Name NVARCHAR(MAX),
Index_ID INT,
Index_Type_Desc NVARCHAR(MAX),
AVG_Fragmentation_in_percent INT,
Fragment_Count INT,
Page_Count INT
)
DECLARE @DB as nvarchar(100);
DECLARE @Command as NVARCHAR(MAX);
DECLARE @FetchFragStatus AS NVARCHAR(max);
DECLARE @Create_Function NVARCHAR(Max);
DECLARE @Drop_Function NVARCHAR(MAX);
DECLARE DB_USE cursor for
SELECT [Name] FROM sys.databases
OPEN DB_USE
FETCH NEXT FROM DB_USE
INTO @DB
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Command = 'USE ' + @DB
SET @Drop_Function = 'USE ' + @DB + ' IF OBJECT_ID (N''dbo.Index_fragmentation'', N''IF'') IS NOT NULL
DROP Function dbo.index_fragmentation'
SET @Create_Function =
'Create function dbo.index_fragmentation()
RETURNS TABLE AS
RETURN
(
SELECT
DB_NAME(database_ID) AS Database_Name,
OBJECT_NAME(ps.object_id) as [Object_Name],
i.Name AS Index_Name,
ps.index_id,
index_type_desc,
avg_fragmentation_in_percent,
fragment_count,
page_count
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ''Limited'') AS ps
INNER JOIN
sys.indexes AS i WITH (NOLOCK)
ON ps.[object_id] = i.[object_id]
AND ps.index_id = i.index_id
WHERE database_id = DB_ID()
--AND page_count > 500
AND avg_fragmentation_in_percent >= 20)'
PRINT (@command)
EXEC sp_executesql @Command
--PRINT (@Drop_Function)
--EXEC (@Drop_Function)
PRINT (@Create_function)
EXEC sp_executesql @Create_function
FETCH NEXT FROM DB_USE
INTO @DB
END
CLOSE DB_USE
DEALLOCATE DB_USE
DECLARE DB_USE cursor for
SELECT [Name] FROM sys.databases
OPEN DB_USE
FETCH NEXT FROM DB_USE
INTO @DB
WHILE @@FETCH_STATUS = 0
BEGIN
SET @FetchFragStatus = 'USE ' + @DB +
' INSERT INTO #T1 (Database_Name, Object_Name, Index_Name, index_Id, index_type_desc, avg_fragmentation_in_percent, fragment_count, page_count)
SELECT * FROM dbo.Index_Fragmentation()'
PRINT (@FetchFragStatus);
EXEC (@FetchFragStatus);
FETCH NEXT FROM DB_USE
INTO @DB
END
CLOSE DB_USE
DEALLOCATE DB_USE
--DECLARE @DB_Name NVARCHAR(100);
--DECLARE @Index_Name NVARCHAR(100);
--DECLARE @Alter_index NVARCHAR(MAX);
--DECLARE @Obj_Name NVARCHAR(MAX);
--
--DECLARE Fragmented_index_Cur Cursor For
--SELECT Database_Name, Index_Name, [Object_Name]
--FROM #T1
--
--OPEN Fragmented_index_cur
--FETCH NEXT FROM Fragmented_index_cur
--INTO
[email protected]_Name, @Index_Name, @Obj_Name
--WHILE @@FETCH_STATUS = 0
--BEGIN
--SET @Command = 'USE ' + @DB_NAME
--SET @Alter_index = 'ALTER Index ' + @Index_Name + ' ON ' + @Obj_Name + ' REBUILD;'
--PRINT (@command)
--EXEC (@command)
--PRINT (@Alter_Index)
--EXEC (@Alter_index)
--
--FETCH NEXT FROM Fragmented_index_cur
--INTO @DB_Name, @Index_Name, @Obj_Name
--
--END
--CLOSE Fragmented_index_cur
--DEALLOCATE Fragmented_index_cur
SELECT * FROM #T1
RETURN;
END
EXEC sp_index_maintenance