【问题标题】:Sql Command (Exception calling "ExecuteScalar" with "0" argument)Sql 命令(使用“0”参数调用“ExecuteScalar”的异常)
【发布时间】:2017-01-19 22:59:13
【问题描述】:

当我第一次尝试运行下面的代码时,我得到一个无法解释的错误,但在第二次尝试再次运行脚本时效果很好...我的代码有什么问题?

顺便说一句,我是在这一步之前创建数据库的……

  $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
  $SqlConnection.ConnectionString = "Server=$dBServer;Database=$dBName;Integrated Security=True" 
  $SqlConnection.Open() 

  $SqlCmd = New-Object System.Data.SqlClient.SqlCommand 
  $SqlCmd.CommandText = $dBCmd 
  $SqlCmd.Connection = $sqlConnection 

  $execute = $SqlCmd.ExecuteScalar() 
  $SqlConnection.Close() 

错误

Exception calling "ExecuteScalar" with "0" argument(s): "A transport-level error has occurred when sending the request to the server. (provider: Shared Memory  Provider, error: 0 - No process is on the other end of the pipe.)" At c:\scripts\DB\Powershell\RunSql.ps1:61 char:34
+   $execute = $sqlCmd.ExecuteScalar <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

【问题讨论】:

    标签: powershell powershell-2.0


    【解决方案1】:

    如果您尝试使用由服务器重置的连接执行命令,则会发生这种常见错误。每当我运行 Powershell 脚本、重新启动 SQL Server,然后再次尝试运行脚本时,都会发生这种情况。该脚本认为连接仍处于打开状态,但是当它尝试使用它时,您会收到传输级错误并关闭连接。当您尝试再次运行脚本时,它将重新建立连接并且一切正常。

    如果你想强制它关闭连接,只需在重启 SQL 服务器时执行 $SqlConnection.Close() 语句即可。

    【讨论】:

    • 抱歉回复晚了,但我认为有电子邮件警报检查...我尝试设置服务重启,然后尝试了几次,只是再次遇到同样的问题...所以我试图设置 $lastExitCode 检查以防万一他们是一个错误,但我一直得到 3 号天气 sql 查询是否成功执行。我厌倦了在打开新连接之前使用 $sqlConnection.Close() ,但仍然没有希望。
    【解决方案2】:

    您是否检查过 SQL Server 配置管理器以确保启用了“命名管道”(在“SQL Server 网络配置 -> SQL 协议...”下)?

    【讨论】:

    • 有时可能是因为Sql Browser服务没有运行或者防火墙异常中不允许。
    • 抱歉回复晚了,但我认为检查了电子邮件警报,是的,命名管道已启用。
    【解决方案3】:

    对于我的奇怪情况,我终于找到了一个可接受的解决方案,使用 $error 变量而不是($LastExitCode 或 $?)来检测 sql 查询失败并循环几次尝试,因为我的代码在第二次尝试后工作。

    $attempts = 0
    $maxAttempts = 3
    
      while ($attempts -lt $maxAttempts)
      {
        $attempts++
        $error.clear() # Clears teh error variable incase of any previous errors in the script
    
          $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 
          $SqlConnection.ConnectionString = "Server=$dBServer;Database=$dBName;Integrated Security=True"  
          $SqlConnection.Open()  
    
          $SqlCmd = New-Object System.Data.SqlClient.SqlCommand  
          $SqlCmd.CommandText = $dBCmd  
          $SqlCmd.Connection = $sqlConnection  
    
          $execute = $SqlCmd.ExecuteScalar()  
          $SqlConnection.Close()  
    
          if ($error.count -eq 0)
          {
            write-host "Sql Query was Successful."            
            break
          }        
    
          else
          {   
            write-host "Sql Query failed on attempt $attempts"
            $error.clear()
          }
      }
    

    【讨论】:

      【解决方案4】:

      我认为你可以强制它直接进入 tcp(1433) 并跳过使用命名管道连接

      "服务器=$dBServer,1433;数据库=$dBName;集成安全=True"

      许多库、客户端首先尝试命名管道,但通常最佳做法是让 1433 监听您的目标。我认为 Ozie 的代码也可以工作......尝试命名管道很简单,失败,尝试 1433,这是 MS 通常工作的标准方式。您可以尝试使用其他人描述的网络库等进行 fussign,但是使用正确的 conn 字符串通常是一个好主意,这样您就知道您将哪个端口用于防火墙等。

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题,我设法通过将连接字符串移动到实例化连接的同一行来解决它。

        $SqlConnection = New-Object System.Data.SqlClient.SqlConnection $conString
        

        不知道为什么,但事后分配它不起作用。也许有人可以解释为什么?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-02
          • 1970-01-01
          • 2014-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多