Sql server System.Data.SqlClient正在将存储过程中的SQL Server PRINT语句与RAISERROR消息连接起来

Sql server System.Data.SqlClient正在将存储过程中的SQL Server PRINT语句与RAISERROR消息连接起来,sql-server,sql-server-2017,raiserror,system.data.sqlclient,Sql Server,Sql Server 2017,Raiserror,System.data.sqlclient,我的相当简单的存储过程在第44行执行此操作: IF @a = @b RAISERROR('blah blah blah', 11, 1) RETURN 使用.NET FrameworkSystem.Data.SqlClient库在客户端调用存储过程: try { SqlCommand c = new SqlCommand(); c.CommandType = CommandType.StoredProcedure; c

我的相当简单的存储过程在第44行执行此操作:

IF @a = @b
    RAISERROR('blah blah blah', 11, 1)
    RETURN
使用.NET Framework
System.Data.SqlClient
库在客户端调用存储过程:

   try
   {
        SqlCommand c = new SqlCommand();
        c.CommandType = CommandType.StoredProcedure;
        c.CommandText = "procname";
        c.ExecuteNonQuery()   // execute the stored procedure 
   }
   catch(SqlException sex)
       throw sex;
   catch(Exception ex)
   {
        throw ex;
   }
当捕捉到
ex
时,其值为
blah blah blah
+CRLF+
1259


1259
是从哪里来的?是否与严重程度11相对应?

啊哈!刚找到。在错误上方的几行有一个
PRINT
语句。不知道(不相关的)打印语句会附加到错误消息中

  PRINT 'Fee fie fo fum'

  <snip>

  if @a = @b
     RAISERROR('blah blah blah', 11, 1)
     return
打印“费用费”
如果@a=@b
RAISERROR('blah blah blah',11,1)
回来

客户端SqlException消息属性是“blah blah blah”+CRLF+“Fee fie fo fum”

FYI,您应该真正使用
THROW
,而不是
RAISERROR
@Larnu:Legacy SP,它早于THROW.@Larnu。我没有使用不受支持的SQL Server版本。我正在使用SQL Server 2017,但该应用程序的许多SP可追溯到好几年前。请改为捕获
SqlException
。它有一个
Errors
属性,具有更细粒度的详细信息。“不知道(不相关的)打印语句会附加到错误消息中!”它们不知道。它们知道。我把它改为“打印‘费费费’”,现在我的错误消息客户端显示为
blah blah blah
+CRLF+
Fee fie fo fum
。必须是
System.Data.SqlClient
功能。与
SqlException
行为相同。数据库引擎将
PRINT
RAISERROR
THROW
生成的所有消息以及信息、警告、错误和API消息返回给客户端。区别在于严重性为11或更高(
SqlError.Class
>=11)的错误也会引发SqlClient和大多数其他API的异常。但是,
SqlException.Errors
集合将包含所有消息,因此您需要在
Class
上进行筛选以丢弃信息和警告消息。谢谢@Dan Guzman。我以前从未在PRINT和RAISERROR以及System.Data.SqlClient中遇到过这种行为。