Transaktion mit mehreren SQLCMD-Aufrufen in einer Batchdatei


7

Gibt es eine gute Möglichkeit, Folgendes zu tun?

SQLCMD -S %SERVER% -E -Q "BEGIN TRANSACTION"
FOR %%f in (script1 script2 script3) do (
    SET CURRENT_SCRIPT=%%f
    SQLCMD -S Localhost -E -b -V 1 -i %%f.sql -o %%f.log
    IF !ERRORLEVEL! NEQ 0 GOTO ERROR
    SET CURRENT_SCRIPT=
)
SQLCMD -S %SERVER% -E -Q "COMMIT TRANSACTION"

Es ist möglicherweise besser, vorher einen Datenbank-Snapshot zu erstellen, um ein einfacheres Rollback zu ermöglichen. Obwohl ich gesehen habe, dass Snapshots E / A-intensive Workloads verlangsamen oder die Skripte zu einem kombinieren und die Transaktionsbehandlung hinzufügen.
wBob

Schnappschuss ist definitiv eine Option. Vielen Dank!
Metapher

Antworten:


10

Da jede sqlcmd-Ausführung eine separate Sitzung ist, bedeutet dies, dass Sie keine Transaktionen über diese Ausführungen hinweg haben können. Sie möchten Ihre Skripte in einem einzigen Skript kombinieren, damit Sie tun können, was Sie wollen.

Wenn Sie Ihre Skripte ordnungsgemäß bestellen können, funktioniert der folgende Ansatz in Powershell für Sie:

$scripts = Get-ChildItem "C:\temp\*.sql" |Sort-Object
$fullbatch = @()
$fullbatch += "BEGIN TRANSACTION;"

foreach($script in $scripts){
    $fullbatch += Get-Content $script
}

$fullbatch += "COMMIT TRANSACTION;"

sqlcmd -S localhost -d test -Q "$fullbatch"

Im Wesentlichen lese ich jedes Skript (vorausgesetzt, sie sind korrekt sortiert) in eine einzelne Stapelvariable ein, füge a BEGIN TRANSACTIONund END TRANSACTIONan den Stapel an und führe diese dann als Abfrage innerhalb meiner sqlcmd-Ausführung zurück.


1
Interessante Idee. Ich müsste alle Skripte (ungefähr 15) ändern, um sicherzustellen, dass die Variablennamen unterschiedlich sind, um sie in denselben Stapel zu legen. Danke für den Vorschlag!
Metapher
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.