【问题标题】:Why does a SqlException thrown by SqlCommand.ExecuteNonQuery contain all the PRINTs as errors?为什么 SqlCommand.ExecuteNonQuery 抛出的 SqlException 包含所有 PRINT 作为错误?
【发布时间】:2011-01-11 19:10:44
【问题描述】:

当我运行以下 sn-p

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.Errors 有 4 个条目(对应于打印的 3 个SqlErrorSqlError.Class 为 0(而实际错误为 18)

但是,如果我将 ExecuteNonQuery 替换为 ExecuteScalar,我会得到预期的结果:

消息是SQL_Error,而我在ex.Errors中只有一个条目...

有什么办法可以避免cmd.ExecuteNonQuery的奇怪行为??

【问题讨论】:

    标签: sql tsql sqlcommand sqlexception


    【解决方案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 中的第一项

    【讨论】:

      【解决方案2】:

      ExecuteNonQuery 通常返回一个记录集,而 ExecuteScalar 返回第一行 + 第一列。

      【讨论】:

      • WExecuteNonQuery 返回受影响的行数(类似于@@ROWCOUNT),并且它具有一些返回值 -1 的好处。 ExecuteReader 返回一个 SqlDataReader。不过,您适合 ExecuteScalar。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      • 2017-05-26
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多