3

次のスニペットを実行すると

try
{
 using (SqlConnection conn = new SqlConnection("I'm shy"))
 {
  conn.Open();

  using (SqlCommand cmd = conn.CreateCommand())
  {
   cmd.CommandText = "PRINT 'A';PRINT 'B';PRINT 'C';RAISERROR('SQL_Error', 18, 1)";
   cmd.ExecuteNonQuery();
  }
 }
}
catch (SqlException ex)
{
 MessageBox.Show(ex.Message);
}

次のメッセージが表示されます。

SQL_Error
A
B
C

ex.Errors4 つのエントリがあります (SqlError出力に対応する 3 の aSqlError.Classは 0 です (対、実際のエラーの場合は 18))。

ただし、に置き換えるExecuteNonQueryExecuteScalar、期待される結果が得られます。

メッセージSQL_Errorex.Errors...

の奇妙な動作を回避する方法はありますcmd.ExecuteNonQueryか??

4

2 に答える 2

1

いいえ、この動作を回避することはできません。これは、TdsParser.ThrowExceptionAndWarning()の記述方法の結果です。

特にこの行

  bool breakConnection = this.AddSqlErrorToCollection(ref temp, ref this._errors) | this.AddSqlErrorToCollection(ref temp, ref this._attentionErrors);
        breakConnection |= this.AddSqlErrorToCollection(ref temp, ref this._warnings);
        breakConnection |= this.AddSqlErrorToCollection(ref temp, ref this._attentionWarnings);

私の推測では、何らかの理由で、コレクション_errorまたは_attentionErrorsのいずれかがExecuteScalerでは空であり、ExecuteNonQueryでは空ではありません。

あなたが十分に突っついていれば、おそらくその理由を見つけることができると確信しています。

いずれにせよ、あなたはすでに回避策を持っているようです。SQLExecption.Errorの最初の項目のみを使用してください

于 2010-02-03T05:47:32.210 に答える
0

ExecuteNonQuery は通常、レコードセットを返しますが、ExecuteScalar は最初の行 + 最初の列を返します。

于 2010-02-01T18:22:11.903 に答える