2

最初の試行で以下のコードを実行すると、原因不明のエラーが発生しますが、2 回目の試行でスクリプトを再度実行すると問題なく動作します...コードのどこが間違っているのでしょうか?

ちなみに、このステップの前にデータベースを作成しています...

  $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
4

5 に答える 5

5

これは、サーバーによってリセットされた接続を使用してコマンドを実行しようとした場合に発生する一般的なエラーです。Powershell スクリプトを実行し、SQL Server を再起動してから、スクリプトを再実行しようとするたびに、この問題が常に発生します。スクリプトは、接続がまだ開いていると見なしますが、それを使用しようとすると、トランスポート レベルのエラーが発生し、接続が閉じられます。スクリプトを再度実行しようとすると、接続が再確立され、すべて正常に動作します。

強制的に接続を閉じたい場合は、SQL サーバーを再起動するたびに $SqlConnection.Close() ステートメントを実行するだけです。

于 2010-03-05T00:08:09.393 に答える
0

強制的にtcp(1433)に直接移動し、次を使用して名前付きパイプ接続の作成をスキップできると思います。

"Server = $ dBServer、1433; Database = $ dBName; Integrated Security = True"

多くのライブラリ、クライアントは最初に名前付きパイプを試しますが、通常のベストプラクティスは、ターゲットで1433をリッスンすることだけです。Ozieのコードも機能すると思います...名前付きパイプを試して失敗し、MSのものがよく機能する標準的な方法である1433を試してみるのは簡単です。他の人が説明しているように、ネットワークライブラリなどでfussignを試すこともできますが、ファイアウォールなどに使用しているポートがわかるように、通常は適切なconn文字列を使用することをお勧めします。

于 2012-03-20T22:50:39.747 に答える
0

私が持っていた奇妙なケースでは、($LastExitCode または $?) の代わりに $error 変数を使用して、SQL クエリの失敗を検出し、コードが 2 回目の試行後に機能するため、いくつかの試行をループすることで、最終的に許容できる解決策に到達しました。

$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()
      }
  }
于 2010-03-05T16:31:06.200 に答える
0

SQL Server 構成マネージャーをチェックして、「名前付きパイプ」が有効になっていることを確認しましたか (「SQL Server ネットワーク構成 -> SQL のプロトコル...」の下)。

于 2010-03-04T16:33:52.580 に答える