Powershell调用sqlcmd以保持连接打开并尝试重用它

Powershell调用sqlcmd以保持连接打开并尝试重用它,powershell,sql-server-2008-r2,Powershell,Sql Server 2008 R2,我有一个Powershell脚本,它使用调用sqlcmd将脚本应用于一系列开发数据库。我循环浏览脚本列表,并将其与数据库的当前版本级别进行比较,然后应用所需的脚本以使数据库达到它需要的版本级别。某些数据库是引用数据库,并且处于只读状态。我连接到这些数据库,运行alterdb脚本,将它们设置为READ_WRITE应用脚本,然后将back更改为READ_ONLY。总的来说,该脚本运行良好,问题在于PowerShell第一次打开与数据库的连接并应用第一个脚本,然后将数据库改回只读,此时数据库已锁定对象

我有一个Powershell脚本,它使用
调用sqlcmd
将脚本应用于一系列开发数据库。我循环浏览脚本列表,并将其与数据库的当前版本级别进行比较,然后应用所需的脚本以使数据库达到它需要的版本级别。某些数据库是引用数据库,并且处于只读状态。我连接到这些数据库,运行alterdb脚本,将它们设置为READ_WRITE应用脚本,然后将back更改为READ_ONLY。总的来说,该脚本运行良好,问题在于PowerShell第一次打开与数据库的连接并应用第一个脚本,然后将数据库改回只读,此时数据库已锁定对象。我将其追溯到上一个连接和一个共享的\u事务\u工作区锁(sys.dm\u tran\u locks),该锁看起来是上一个powershell连接。为什么在
调用sqlcmd
完成后,此连接仍处于打开状态,我可以对此做些什么吗?我是否可以强制
invoke sqlcmd
在每次调用cmdlet时使用新连接


我尝试了一个混乱的修复程序,先删除了有问题的连接,然后重试连接,但我认为还有更好的方法。

好吧,我知道这是一篇非常古老的帖子,微软的人告诉我已经修复了这个问题(正如David Brabant提到的文章所说)但也许我不是最幸运的人,我必须想办法让它发生

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

让我们来看看在我的案例中应用的变通方法
我希望它能有所帮助

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

  • 运行正常命令

  • 准备从数据库中删除连接时:

    Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" -Query "use [master];"
    

  • 这会将连接切换到master,从而将其从感兴趣的数据库中删除。如果您确实需要关闭连接,我认为您需要求助于SqlClient之类的工具。

    我一直都这样做,而且似乎可以:

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

    我认为这是2008年的一个已知bug(2012年修复):另请参见:谢谢,就是它。我将尝试处理连接项。在引入SQL脚本(该脚本将删除并重新创建数据集和/或在数据库上设置单用户/多用户模式)后,我使用了一段时间的PS脚本遇到了问题。从而导致调用sqlcmd的重用连接失败。该脚本之后的ClearAllPools()修复了我的问题,即调用下一个sql脚本会使PS脚本崩溃。谢谢。我在
    foreach
    中使用
    Invoke Sqlcmd
    时遇到问题。第一次迭代成功地执行了脚本,但第二次迭代和其他迭代从未执行过。我在
    调用Sqlcmd
    命令之后添加了
    [System.Data.SqlClient.SqlConnection]::ClearAllPools()
    ,效果非常好。非常感谢。
    Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" -Query "use [master];"
    
    [System.Data.SqlClient.SqlConnection]::ClearAllPools()