c# - 如何从 C# 中的 SQL 存储过程中检索结果集和 PRINT 消息?

标签 c# sql-server stored-procedures resultset

我有一个存储过程,它可以返回 PRINT 消息和来自 SELECT 语句的常规查询结果。使用 this thread 中提供的优雅解决方案,在我的 C# 代码中调用 SqlCommand.ExecuteNonQuery() 时,我可以轻松捕获我的 PRINT 消息。问题是,我也想返回我的结果集。

当我使用 SqlDataReader 从使用 SqlCommand.ExecuteReader 的存储过程取回查询结果时,捕获我的 PRINT 的事件处理程序> 消息永远不会像我使用 SqlCommand.ExecuteNonquery 时那样触发。

我似乎只能选择其中之一。有没有办法让我同时捕获我的 PRINT 消息我的查询结果?

这是我的 SQL 存储过程的片段:

IF EXISTS
(
    SELECT MFG_PART_NUMBER, COUNT(*) AS RecordCount
    FROM [PartsManagement].[ManufacturerCatalogPart] 
    WHERE CatalogID = @CatalogID
    GROUP BY MFG_PART_NUMBER
    HAVING COUNT(*) > 1
)
    BEGIN

    SELECT MFG_PART_NUMBER, COUNT(*) AS RecordCount
    FROM [PartsManagement].[ManufacturerCatalogPart] 
    WHERE CatalogID = @CatalogID
    GROUP BY MFG_PART_NUMBER
    HAVING COUNT(*) > 1;

    PRINT 'The update was not executed because duplicate MFG_PART_NUMBERs were found in the catalog. Delete the duplicates and try again.';

END;

这是我的代码片段:

//field
private string sqlPrintMessage = "";

//event handler for sql PRINT message
void myConnection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    sqlPrintMessage = e.Message;
}

public void SomeMethod()
{
    using (SqlConnection sqlcon = new SqlConnection(ConnectionManager.GetConnectionString()))
    {
        sqlcon.InfoMessage += new SqlInfoMessageEventHandler(myConnection_InfoMessage);

        SqlCommand sqlcmd = new SqlCommand("[ManufacturerCatalogUpdate].[CheckCatalogForDuplicates]", sqlcon);
        sqlcmd.CommandType = CommandType.StoredProcedure;
        sqlcmd.Parameters.AddWithValue("@CatalogID", catalogID);
        sqlcon.Open();
        //SqlDataReader reader = sqlcmd.ExecuteReader();
        sqlcmd.ExecuteNonQuery();
        if (sqlPrintMessage == "") //then proceed with update
        {
            //do some logic
        }
        else
        {
            //System.Diagnostics.Debug.WriteLine(sqlPrintMessage);
            //List<DuplicatePartCount> duplicateParts = new List<DuplicatePartCount>();
            //while (reader.Read())
            //{
            //    DuplicatePartCount record = new DuplicatePartCount();
            //    record.MFG_PART_NUMBER = reader.GetString(0);
            //    record.count = reader.GetInt32(1);
            //    duplicateParts.Add(record);
            //}
        }
    }
}

最佳答案

根据sql执行的选择,有两种方法。

1) 如果您正在使用 ExecuteNonQuery,那么请在存储过程中使用 OUT 参数,如下所示。

CREATE PROCEDURE GetEmployee
   @employeeID INT,
   @Message VarChar(100) OUTPUT
AS
BEGIN
   -- Here is your result set from select statement
   SELECT Emp_Name From Employee Where EmpId = @employeeID 

   -- Here is your message
   SELECT @Message = 'Your Message!'
END

现在要在您的代码中通过 @Message 参数和 OUT 获取它,如下所示。

//Add the output parameter to the command object
SqlParameter outPutParameter = new SqlParameter();
outPutParameter.ParameterName = “@Message”;
outPutParameter.SqlDbType = System.Data.SqlDbType.Varchar;
outPutParameter.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(outPutParameter);

cmd.ExecuteNonQuery();

//Retrieve the value of the output parameter
string Message = outPutParameter.Value.ToString();

// You can get remaining result set as always

2) 如果您使用的是阅读器...

设置消息并使用 Select 语句而不是打印。如下所示'

 SELECT Emp_Name From Employee Where EmpId = @employeeID 
  -- It should be set previously
  SELECT @Message

要进入你的代码只需使用

using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                //Your result set or message
            }

            if(reader.NextResult())
            {
               while (reader.Read())
              {
                 //Your result set or message
              }
            }
        }

关于c# - 如何从 C# 中的 SQL 存储过程中检索结果集和 PRINT 消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30700555/

相关文章:

c# - "Service X has zero application endpoints"除非我在代码中添加端点 - 为什么?

c# - 如何将对象数组传递为 jQuery Ajax 可以理解的格式?

sql-server - 灾难恢复 - 在没有 MDF 的情况下恢复 SQL Server 数据库

mysql - mysql SP 中的 IF/ELSE 结构不起作用

c# - InternetSetCookie 返回 ERROR_INVALID_OPERATION

c# - 如何检测 Windows 10 何时在 Windows 窗体应用程序中进入平板电脑模式?

sql - 将多个时间间隔内的天数相加

c# - 在 c# 代码中使用 dapper 将输出参数传递给存储过程

postgresql - 将数据插入 Postgresql 的存储过程

mysql - 查询获取订单量小于上一个订单量的客户列表