web-dev-qa-db-ja.com

変数を指定して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が行う方法と同じように、上記の変数を置換して出力したいと思います。

1
Alex K

set quoted_identifier offで賢い方法を見つけました

enter image description here

PowerShell

$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
*/
0
Alex K

Invoke-sqlcmdがこれを実行できるとは思いません。通常のsqlcmd.exeには、バッチを出力するための-eパラメータがありますが、 "GO"は出力されません。例えば

sqlcmd -e -i restore.sql -v database="foo" databaseBak="bk" > Restore.final.sql

SET NOEXEC ONを先頭に置くか、ダミーインスタンスにポイントしてスクリプトを生成できます。

または次のようなもの:

sqlcmd -e -Q "set noexec on;`n:r restore.sql" -v database="foo" databaseBak="bk"

ホイールを再発明する代わりに、単に dbatools-restore-dbadatabase を使用します

これまでに必要になる可能性のあるすべてのシナリオを幅広くカバーしています です。

注:dbatoolsには、invoke-sqlcmd-> invoke-sqlcmd2-ParseGOは、GOバッチセパレータを使用してスクリプトを解析し、より最適化されたバージョンです。

0
Kin Shah