[英]XML data coming in newline using invoke-sql command in powershell
[英]PowerShell - How to Commit Scope if all Invoke-SQL Commands are successful
我正在使用 PowerShell 版本 5,并且我正在 PowerShell 脚本中执行几个 SQL 命令。 与 SQL 服务器不同,我们在BEGIN TRANSACTION和COMMIT TRANSACTION中执行命令,因此如果单个命令失败,所有内容都会回滚,我想在我的 Powershell 脚本中实现类似的事情。
因此,在我的场景中,如果有 3 个 SQL 命令失败,则不应删除该表:
在插入记录时,我尝试使用数组插入多行并测试scope的工作,所以我故意添加重复的 Id 值,因此预期结果是如果 Id 即第一个数组元素有效,则继续下一个元素,但如果第二个数组元素无效,然后回滚更改。
但是由于我对 Powershell 的了解有限,因此不确定如何实现这一点,因此即使 ID 不重复或不重复,session 也不会被提交。
到目前为止,以下是我的脚本:
$connString = "Data Source=<Server-Name>;Database=<DB-Name>;User ID=<Login>;Password=<Pass>"
$conn = New-Object System.Data.SqlClient.SqlConnection $connString
$arr_values = @('1','1')
$tbl_name = "dbo.test1"
$conn.Open()
try
{
if($conn.State -eq "Open")
{
foreach ($Id in $arr_values)
{
$scope = New-Object -TypeName System.Transactions.TransactionScope
$Drop_Command= "DROP Table IF EXISTS $tbl_name"
Invoke-Sqlcmd -ServerInstance <Server-Name> -Database <DB-Name> -Query $Drop_Command
$Create_Command = "Create table dbo.test1 (Id int, CONSTRAINT PK_test1_Id PRIMARY KEY (Id))"
Invoke-Sqlcmd -ServerInstance <Server-Name> -Database <DB-Name> -Query $Create_Command
$Insert_Command = "INSERT INTO dbo.test1(Id) Values ($Id)"
Write-Host "$Insert_Command->" $Insert_Command
Invoke-Sqlcmd -ServerInstance <Server-Name> -Database <DB-Name> -Query $Insert_Command
# Start-Sleep -Seconds 10
Write-Host "Record Inserted with Id->" $Id
}
$scope.Complete()
# $scope.Dispose()
}
}
catch
{
Write-Host "Record not Inserted ->" $Id
$_.exception.message
}
finally
{
$scope.Dispose()
$conn.Close()
}
添加到大卫的答案中,您可以使用SqlTransaction
和SqlCommand
对象而不是Invoke-SqlCmd
。 这是基于您问题中的代码的一些示例代码。 我没有尝试纠正原始代码中的错误(例如,表 dbo.test1 create 将在第二次迭代中失败)。
$connString = "Data Source=<Server-Name>;Database=<DB-Name>;User ID=<Login>;Password=<Pass>"
$conn = New-Object System.Data.SqlClient.SqlConnection $connString
$arr_values = @('1','1')
$tbl_name = "dbo.test1"
$conn.Open()
$tran = $conn.BeginTransaction()
try {
foreach ($Id in $arr_values) {
$script = @"
DROP Table IF EXISTS $tbl_name;
Create table dbo.test1 (Id int, CONSTRAINT PK_test1_Id PRIMARY KEY (Id));
INSERT INTO dbo.test1(Id) Values ($Id);
"@
$cmd = New-Object System.Data.SqlClient.SqlCommand($script, $conn)
$cmd.Transaction = $tran
[void]$cmd.ExecuteNonQuery()
Write-Host "Record Inserted with Id->" $Id
}
$tran.Commit()
}
catch {
$tran.Rollback()
Write-Host "Record not Inserted ->" $Id
$_.exception.message
}
finally {
$conn.Close()
}
Invoke-SqlCmd
是一种方便的方法。 构建一个包含所有事务处理的脚本并将其传递给Invoke-SqlCmd
,或者直接使用SqlConnection
、 SqlCommand
、 SqlTransaction
对象。
而且我不确定TransactionScope
在 PowerShell 中是否有效。
我对 PowerShell 一无所知,但您似乎试图以错误的方式解决问题。
SQL 有 2 组命令:DDL - 数据定义语言和 DML - 数据操作语言。
事务(如果 db 引擎支持它们)可以与 DML 一起正常工作。 要使用 DDL 支持事务,您不应依赖它。 这有点理论。
你可以做什么 - 重新排序和改变一点,以保证你想要什么:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.