Powershell Invoke-sqlcmd 保持连接打开并尝试重用它

Ste*_*ich 5 powershell sql-server-2008-r2

我有一个使用 Powershell 脚本 invoke-sqlcmd将脚本应用于一系列开发数据库。我遍历脚本列表并将其与数据库的当前版本级别进行比较,然后应用所需的脚本使数据库达到它需要的版本级别。某些数据库是参考数据库并且处于 READ_ONLY 状态。我连接到那些数据库,运行一个更改数据库脚本,将它们设置为 READ_WRITE 应用该脚本,然后将其更改回 READ_ONLY。总体而言,脚本运行良好,问题在于当 PowerShell 首先打开与数据库的连接并应用第一个脚本,然后将数据库更改回 READ_ONLY 时,数据库已锁定对象。我已经将它追溯到以前的连接和一个 Shared_Transaction_Workspace 锁 (sys.dm_tran_locks) 看起来是以前的 powershell 连接。invoke-sqlcmd已经完成,我能做些什么吗?我可以强制invoke-sqlcmd为每次调用 cmdlet 使用新连接吗?

我尝试了一个凌乱的修复,杀死有问题的连接,然后重试连接,但我认为有更好的方法。

Pau*_*ler 8

我一直这样做,它似乎工作:

[System.Data.SqlClient.SqlConnection]::ClearAllPools()
Run Code Online (Sandbox Code Playgroud)


小智 2

好吧,我知道这是一篇非常老的帖子,微软的人告诉我们解决了这个问题(正如 David Brabant 提到的文章所述),但也许我不是最幸运的人,必须采取解决方法才能实现这一点。

即使运行 Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64) 我也遇到了同样的问题,经过一些研究后,我找到了一种从 Invoke-Sqlcmd 获取一些参数作为输出的方法,这样我就可以获得当前的会话 ID用户进程使用 SQL Server 中的内置 @@SPID 全局变量并与 ADO.NET 建立连接以执行 KILL 子句以关闭打开的连接。

那么让我们看看适用于我的案例的解决方法

#Invoke the Invoke-Sqlcmd to execute an script from a file
Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -InputFile [DOT_SQL_FILE_PATH]
#Invoke the Invoke-Sqlcmd to execute a inline SQL statement to get the SessionID as a Powershell variable
$SQLSession = Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -query "select @@spid as SessionID"
# Build query to execute KILL clause
$DbQuery = "KILL " + $SQLSession.SessionID;

# Create SQL connection with ADO.NET
$DbConnection = New-Object System.Data.SqlClient.SqlConnection
$DbConnectionString = "Server = [SERVER_NAME]; Database = [DATABASE_NAME]; User ID=[USER]; Password=[PASSWORD];"
$DbConnection.ConnectionString = $DbConnectionString
$DbConnection.Open()

# Create SQL command for KILL clause
$DbCommand = New-Object System.Data.SQLClient.SQLCommand  
$DbCommand.Connection = $DbConnection 
$DbCommand.CommandText = $DbQuery 

# Execute KILL clause
$DbCommand.ExecuteNonQuery()

# Close connection
$DbConnection.Close()
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助