我们如何在一个事务中运行多个 SQL 脚本,其中每个脚本可能定义相同的变量?
文件1:
declare @tableName varchar(28), @query nvarchar(1000)
set @tableName = '1apples'+convert(varchar(28), getdate(),121)
select @query = 'select name into ' + quotename(@tableName) + ' from sys.objects'
print @query
exec (@query)
go
文件2:
declare @tableName varchar(28), @query nvarchar(1000)
set @tableName = '2apples'+convert(varchar(28), getdate(),121)
select @query = 'select name into ' + quotename(@tableName) + ' from sys.objects'
print @query
exec (@query)
go
我正在 PowerShell 中执行这样的文件:
try {
$files = Get-ChildItem -Path $SqlFilesDirectory -File -Filter *.sql
$filesSorted = $files |Sort-Object -Property Name
$filesconcatenated = @(
$files |Get-Content -Raw
) -join [Environment]::NewLine
$filesconcatenated = 'SET XACT_ABORT ON ' + $filesconcatenated + ' SET XACT_ABORT OFF ' + [Environment]::NewLine
$cmd = New-Object System.Data.SqlClient.SqlCommand ($filesconcatenated), $conn
$cmd.Transaction = $tran
[void]$cmd.ExecuteNonQuery()
$tran.Commit()
}
catch {
$tran.Rollback()
Write-Host "Record not Inserted ->"
$_.exception.message
}
finally {
$conn.Close()
}
我遇到以下异常:
Exception calling "ExecuteNonQuery" with "0" argument(s): "Incorrect syntax near the keyword 'declare'. The variable name '@tableName' has already been declared. Variable names must be unique within a query batch or stored procedure. The variable name '@tableName' has already been declared. Variable names must be unique within a query batch or stored procedure. Incorrect syntax near the keyword 'SET'."
我们如何在一个事务中运行多个 SQL 脚本,其中每个脚本可能定义相同的变量?
这是它尝试运行的完整脚本:
SET XACT_ABORT ON
declare @tableName varchar(28), @query nvarchar(1000)
set @tableName = '1apples'+convert(varchar(28), getdate(),121)
select @query = 'select name into ' + quotename(@tableName) + ' from sys.objects'
print @query
exec (@query)
go
declare @tableName varchar(28), @query nvarchar(1000)
set @tableName = '2apples'+convert(varchar(28), getdate(),121)
select @query = 'select name into ' + quotename(@tableName) + ' from sys.objects'
print @query
exec (@query)
go
declare @tableName varchar(28), @query nvarchar(1000)
set @tableName = '3apples'+convert(varchar(28), getdate(),121)
select @query = 'select name into ' + quotename(@tableName) + ' from sys.objects'
print @query
exec (@query)
go
SET XACT_ABORT OFF
最佳答案
在一个批处理中不能两次使用相同的变量
因此,通过循环数组将它们作为单独的命令执行
$connString = "Server=tcp:$ServerName.database.windows.net,1433;Database=$DBName;User Id=$SvcAdminAccount@$ServerName;Password=$SvcAdminPassword;MultipleActiveResultSets=true;Persist Security Info=true;";
$conn = New-Object System.Data.SqlClient.SqlConnection $connString try
{
$conn.Open()
$files = Get-ChildItem -Path $SqlFilesDirectory -File -Filter *.sql
$filesSorted = $files |Sort-Object -Property Name
$tran = $conn.BeginTransaction()
foreach ($file in $filesSorted)
{
$query = "SET XACT_ABORT ON; " + (Get-Content -Raw $file)
$cmd = New-Object System.Data.SqlClient.SqlCommand ($query, $conn, $tran)
[void]$cmd.ExecuteNonQuery()
}
$tran.Commit();
}
catch {
Write-Host "Record not Inserted ->"
$_.exception.message
}
finally {
$tran.Dispose()
$conn.Dispose()
}
Note the way
Dispose
is used, rather thanRollback
, becauseDispose
will never throw an exception. It's also in thefinally
rather than thecatch
关于sql - 变量名称在查询批处理或存储过程中必须是唯一的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69789274/