2012-12-20 49 views
5

如何確保在一次傳輸中運行以下語句?Multiple Invoke-SqlCmd和Sql Server事務

try 
{ 
    Invoke-SqlCmd -Query 'begin tran; ...sql script...' 
    # Other Powershell script 
    Invoke-SqlCmd -Query '...sql script...; if @@transcation > 0 commit tran' 
} 
catch 
{ 
    Invoke-SqlCmd -Query 'if @@transaction > 0 rollback tran;' 
} 

什麼是在事務中運行Powershell腳本的最佳方法?

+0

的PowerShell:

提交將被使用您的範圍,所以工作示例,以保證承諾會完全像這樣之後加入明確的處置年底執行有開始交易,這是你指的是什麼? http://technet.microsoft.com/en-us/library/hh849772.aspx –

+0

@ShawnMelton不,我試過'開始交易; Invoke-Sqlcmd'select 1 a into ## test'-ServerInstance myserver; 撤消事務處理,它仍然創建表。 – ca9163d9

回答

2

Invoke-sqlcmd不支持ADO.NET轉換。您有兩種解決方法,可以將等效Powershell代碼寫入此MSDN文檔中顯示的用於ADO.NET事務的C#代碼: http://msdn.microsoft.com/en-us/library/2k2hy99x(v=vs.110).aspx

或使用T-SQL事務。不添加T-SQL Try/Catch到每個腳本的快速方法是將XACAT_ABORT設置爲ON;然後在開始和提交事務中包裝腳本。請記住,這可能趕不上終止錯誤:

http://msdn.microsoft.com/en-us/library/ms188792.aspx

4

不幸的是,SqlProvider在PowerShell中不具有事務處理能力像Registry提供商。因此Start-transaction在這裏不起作用。

你可以去本地和利用TransactionScope類。這是$範圍分配和$scope.complete()之間放

Try{ 
    $scope = New-Object -TypeName System.Transactions.TransactionScope 

    Invoke-Sqlcmd -server Darknite -Database AdventureWorks2008 -Query $Query1 -ea stop 
    Invoke-Sqlcmd -server Darknite -Database AdventureWorks2008 -Query $Query2 -ea stop 

    $scope.Complete() 
} 
catch{ 
    $_.exception.message 
} 
finally{ 
    $scope.Dispose() 
} 

所有調用-sqlcmds,將被視爲一個事務。如果它們中的任何一個出錯,所有都將被回滾。

0

我最近公佈了與數據庫交互,支持交易一個新的模塊:

Install-Module -Name InvokeQuery 

你不需要如果發生錯誤,明確回滾。使用Start-Transaction創建的環境交易將爲您負責。

try { 
    $db = "test" 
    Start-Transaction 

    $sql = "insert into table1 values (NEWID(), 8765, 'transactions!', GETDATE())" 
    $rowcount = $sql | Invoke-SqlServerQuery -Database $db -UseTransaction -CUD -Verbose 
    Write-Host "Inserted $rowcount rows!" 

    $sql = "insert into table1 values (NEWID(), 5555, 'transaction too!', GETDATE())" 
    $rowcount = $sql | Invoke-SqlServerQuery -Database $db -UseTransaction -CUD -Verbose 
    Write-Host "Inserted $rowcount rows!" 

    Complete-Transaction 
} 
catch { 
    ##Transaction will automatically be rolled back.... 
    Write-Error $_ 
} 

如果你想明確地滾動事務中背部則拋出一個錯誤:

throw 'rollback because of reason X!' 

更多的例子: https://github.com/ctigeek/InvokeQueryPowershellModule/blob/master/README.md#transactions