Sql-Server
游標/While 循環是對多個數據庫進行管理更改的唯一方法嗎?
我特別想要一種可程式的方式來更改伺服器上所有數據庫的恢復模型,並且我知道這個解決方案可以應用於所有“更改數據庫”命令。雖然我知道 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
- 這也可以通過 while 循環來完成,但該解決方案仍會經歷一個循環過程…… while 循環是否提供了明顯更好的性能?
- 我對性能有偏執嗎?我這麼說是因為諸如此類的管理任務並不經常執行,而且通常不需要循環遍歷大量對象。然而,我總是想“如果我在一個包含數千個對象的大型環境中工作會怎樣”,然後我開始感到內疚,因為我可能沒有使用最有效的解決方案。
就這類事情的循環而言,不用擔心。循環和游標的名聲不好,因為通常有更好的基於集合的方法通常更快。對於管理的東西,有時循環是唯一的方法,並且沒有基於集合的方法來做這個春天,儘管你可以使用 DOS、SSIS、Powershell 等工具來並行化任務。
話雖如此,我更喜歡對這類事情使用SQLCMD模式。這是一種特殊模式,您可以通過主菜單 > 查詢 > SQLCMD 模式在 SQL Server Management Studio (SSMS) 中打開…如下所示:
開啟此模式後,您可以訪問各種命令,例如
: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 模式!