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

问题描述 投票:4回答:3

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

我尝试了一个混乱的修复程序来杀死有问题的连接,然后重试连接,但我认为有更好的东西。

powershell sql-server-2008-r2
3个回答
2
投票

我一直这样做,似乎有效:

[System.Data.SqlClient.SqlConnection]::ClearAllPools()

1
投票

嗯,我知道这是一个非常古老的帖子,来自微软的人告诉我解决了这个问题(正如David Brabant所提到的那篇文章),但也许我不是最幸运的人,必须做一个解决方法才能让它发生。

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

So let's to the workaround applied in my case

#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()

我希望它有所帮助


0
投票

即使我使用的是最新版本的SSMS(版本16.5.3 - Build 13.0.16106.4),我仍然会遇到这个问题。我还没弄清楚强制连接关闭的“正确”方式是什么,但我有一个简单的解决办法,并为我解决了问题。如果您只需要从数据库中获取连接,则可以执行以下操作:

  1. 运行正常命令 Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" ...
  2. 当您准备从数据库中消除连接时: Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" -Query "use [master];"

这会将连接切换到master,从而将其从感兴趣的数据库中删除。如果你绝对需要关闭连接,我认为你需要求助于SqlClient等。

© www.soinside.com 2019 - 2024. All rights reserved.