Sql-Server

游標/While 循環是對多個數據庫進行管理更改的唯一方法嗎?

  • May 1, 2016

我特別想要一種可程式的方式來更改伺服器上所有數據庫的恢復模型,並且我知道這個解決方案可以應用於所有“更改數據庫”命令。雖然我知道 PowerShell 中的 SMO 可以很容易地解決這個問題:

Import-Module SQLPS
CD SQL\*ServerName*\*InstanceName*\databases
foreach ($database in (ls -force)){
$database.recoverymodel = 'Full'
$database.update
}

我正在尋找最有效的 T-SQL 解決方案。不惜一切代價避免使用游標已經在我的腦海中根深蒂固,但是我想不出一個基於集合的解決方案來執行更改語句。這是基於游標的解決方案。

DECLARE @sql varchar(MAX), @name varchar(50)

DECLARE cur CURSOR FOR
SELECT name 
FROM sys.databases
where name <> 'tempdb';
OPEN cur

FETCH NEXT FROM cur 
INTO @name

WHILE @@FETCH_STATUS = 0
BEGIN
   SET @sql = 'ALTER DATABASE ' + @name + ' SET RECOVERY FULL;'
   exec(@sql)
   FETCH NEXT FROM cur INTO @name
END
CLOSE CUR
DEALLOCATE cur
  1. 這也可以通過 while 循環來完成,但該解決方案仍會經歷一個循環過程…… while 循環是否提供了明顯更好的性能?
  2. 我對性能有偏執嗎?我這麼說是因為諸如此類的管理任務並不經常執行,而且通常不需要循環遍歷大量對象。然而,我總是想“如果我在一個包含數千個對象的大型環境中工作會怎樣”,然後我開始感到內疚,因為我可能沒有使用最有效的解決方案。

就這類事情的循環而言,不用擔心。循環和游標的名聲不好,因為通常有更好的基於集合的方法通常更快。對於管理的東西,有時循環是唯一的方法,並且沒有基於集合的方法來做這個春天,儘管你可以使用 DOS、SSIS、Powershell 等工具來並行化任務。

話雖如此,我更喜歡對這類事情使用SQLCMD模式。這是一種特殊模式,您可以通過主菜單 > 查詢 > SQLCMD 模式在 SQL Server Management Studio (SSMS) 中打開…如下所示:

SSMS 中的 SQLCMD 模式

開啟此模式後,您可以訪問各種命令,例如:connect連接到另一台伺服器、:r讀取文件、:out重定向輸出、SQLCMD 變數和任何 DOS 命令,方法是在它們前面加上兩個驚嘆號,例如!!dir.

對於您的範例,您可以執行以下操作:

:connect .\sql2014
SET NOCOUNT ON
GO

-- Redirect output back to normal
:out d:\temp\temp.sql
GO

SELECT 'ALTER DATABASE ' + name + ' SET RECOVERY FULL;'
FROM sys.databases
WHERE recovery_model_desc != 'FULL'
 AND database_id > 4
 AND name Not In ( 'distribution', 'SSISDB' )
GO

PRINT 'GO'
GO
-- Redirect output back to normal
:out STDOUT

-- Optionally read/run the temp file you have scripted
--:r d:\temp\temp.sql
GO

這允許您“編寫腳本”,然後您可以查看它,根據需要進行更改,並且對已執行的內容進行審計跟踪。試試 SQLCMD 模式!

引用自:https://dba.stackexchange.com/questions/137097