English 中文(简体)
Why does a SqlException thrown by SqlCommand.ExecuteNonQuery contain all the PRINTs as errors?
原标题:

When I run the following snippet

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);
}

I get the following message:

SQL_Error
A
B
C

and ex.Errors has 4 entries (The 3 SqlError s corresponding to the prints have a SqlError.Class of 0 (vs. 18 for the real error)

However, if I replace ExecuteNonQuery with ExecuteScalar, I get the expected result:

The message is SQL_Error and I only have one entry in ex.Errors...

Is there any way to avoid the strange behavior of cmd.ExecuteNonQuery??

最佳回答

No you can t avoid this behavior. Its the result of the way TdsParser.ThrowExceptionAndWarning() is written

particularly this line

  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);

My guess is that for whatever reason one of the collection _error or _attentionErrors is empty for ExecuteScaler and its not for ExecuteNonQuery.

I m sure if you poked around enough you could probably find out why.

In any case you seem to have the workaround already. Only use the first item in SQLExecption.Error

问题回答

ExecuteNonQuery normally returns a recordset while ExecuteScalar returns the first row + first column.





相关问题
How to write this T-SQL WHERE condition?

I ve got two tables: TableA Col1 Col2 TableB Col3 Col4 I want to join them together: SELECT * from TableA join TableB ON (...) Now, in place of ... I need to write an expression ...

Customer and Order Sql Statement

TSQL query to select all records from Customer that has an Order and also select all records from customer that does not have an Order. The table Customer contains a primary key of CustomerID. The ...

Recommended way of querying multiple Versioned tables

Have a win 2003 box with MSSQL 2005 running on it. There is a database which is populated every morning with new/modified SalesOrder made the previous day. The database has several tables: SalesOrder, ...

update duplicate record

I have a table with the following fields Id Name IsPublic i need to write a sql query that updates IsPublic to false where name has a duplicate. Only one of the duplicates should have IsPublic = ...

Define variable to use with IN operator (T-SQL)

I have a Transact-SQL query that uses the IN operator. Something like this: select * from myTable where myColumn in (1,2,3,4) Is there a way to define a variable to hold the entire list "(1,2,3,4)"? ...

Selecting records during recursive stored procedure

I ve got a content management system that contains a hierarchical structure of categories, with sub-categories subject to different ordering options at each level. Currently, that s retrieved by a (...

热门标签