Sql-Server
如何使用帶變數的 Invoke-SqlCmd 僅輸出 SQL 命令或其他類似方法?
我有一個
*.sql
執行的大文件Invoke-Sqlcmd
和用於執行某些任務的變數,當我遇到問題時,由於變數而調試很痛苦,我想記錄即將執行的 SQL 腳本。是否有一種合理的本地方式來生成最終
SQL
將通過變數替換執行而不實際執行?這是我執行以將 *.bak 恢復到各種環境的範例:
Invoke-Sqlcmd -InputFile $sqlFile -QueryTimeout 0 -ServerInstance 'SQLServer' -Database 'Master' -Variable @("DatabaseBAK=$TransactDB", "Database=$TargetDatabase") -Verbose
SQL 文件:
USE [master] print 'Killing connections to database $(Database)' DECLARE @kill varchar(8000) = ''; SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), session_id) + ';' FROM sys.dm_exec_sessions WHERE database_id = db_id('$(Database)') and session_id <> @@SPID EXEC(@kill); GO USE [master] print '[Info] RESTORE DATABASE [$(Database)]' print '[Info] FROM DISK = N''$(DatabaseBAK)''' print 'Starting restore-------------------->' RESTORE DATABASE [$(Database)] FROM DISK = N'$(DatabaseBAK)' WITH FILE = 1 ,NOUNLOAD ,REPLACE ,STATS = 5 GO print '<--------------------End restore'
我想以某種方式以 Invoke-SqlCmd 的方式輸出上面的變數替換。
我想出了一個聰明的方法
set quoted_identifier off
電源外殼
$sqlFile = "C:\Users\user\Desktop\TestOutput.sql" $begin = 'set quoted_identifier off print "' $end = '" set quoted_identifier on' Invoke-Sqlcmd -InputFile $sqlFile -QueryTimeout 0 -ServerInstance 'Server' -Database 'Database' -Variable @("begin=$begin", "end=$end") -Verbose $begin = '--Begin' $end = '--End' Invoke-Sqlcmd -InputFile $sqlFile -QueryTimeout 0 -ServerInstance 'Server' -Database 'Database' -Variable @("begin=$begin", "end=$end") -Verbose
TSQL
/* $(begin) is either set quoted_identifier off print " or --Begin */ $(begin) select SALESID from SALESTABLE where SALESID = 'SO-000003' select SALESID from SALESTABLE where SALESID = 'SO-000004' $(end) /* $(end) is either " set quoted_identifier on or --End */
無需重新發明輪子,只需使用dbatools - restore-dbadatabase
注意:dbatools 也有更好的 invoke-sqlcmd –> invoke-sqlcmd2版本,
-ParseGO
可以使用批處理分隔符來解析腳本,GO
並且是更優化的版本。