Sql命令(使用“0”参数调用“ExecuteScalar”的异常)

时间:2010-03-04 15:17:44

标签: powershell powershell-v2.0

当我第一次尝试运行下面的代码时,我得到一个无法解释的错误,但是第二次尝试再次运行脚本工作正常......我的代码会出错?

顺便说一下,在此步骤之前我正在创建数据库...

  $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

5 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

对于我的奇怪案例,我终于通过使用$ 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()
      }
  }

答案 3 :(得分:0)

我认为您可以强行直接使用tcp(1433)并使用

跳过命名管道连接

“Server = $ dBServer,1433; Database = $ dBName; Integrated Security = True”

许多图书馆,客户端首先尝试命名管道,但通常最佳做法是只有1433监听目标。我认为Ozie的代码也很有用......尝试命名管道很简单,失败,尝试1433这是MS事物经常工作的标准方式。您可以像其他人所描述的那样尝试使用网络库等,但使用正确的连接字符串通常是一个好主意,因此您知道您使用哪个端口用于防火墙等。

答案 4 :(得分:0)

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

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

不确定原因,但之后分配它不起作用。也许有人可以解释为什么?