在C#中捕获嵌套存储过程的输出

时间:2018-04-30 16:21:42

标签: sql-server stored-procedures return-value

我从另一个存储过程(1)中调用一个存储过程(2)。两个存储过程最后都以SELECT语句的形式返回数据集。我需要在我的c#代码中捕获这两个,但是,我的代码只捕获存储过程的Select数据集(2)。请指导我如何实现这一目标?

以下是程序的格式:

CREATE PROCEDURE dbo.GoalStop
    @ID INT,
    @StopDate [DATETIME] = NULL
WITH EXECUTE AS CALLER
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Return varchar(500);
    BEGIN TRY
        UPDATE dbo.Table2
        SET StopDate = @StopDate 
        WHERE TableID = @ID

        SET @Return = 'The Goal was successfully stopped.';

        SELECT 'DATABASE MESSAGE: ' + @Return
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK

        DECLARE @ErrMsg VARCHAR(4000), @ErrSeverity INT

        SELECT 
            @ErrMsg = ERROR_MESSAGE(), 
            @ErrSeverity = ERROR_SEVERITY()

        RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH
END

调用存储过程是:

CREATE PROCEDURE [dbo].[Goal_Restart]
    @ID [INT],
    @Goal [DECIMAL](18, 8) = NULL,
    @StartDate [DATETIME] = NULL,
    @StopDate [DATETIME] = NULL,
    @Updatedby [VARCHAR](8),
    @UpdateDate [DATETIME] = NULL
WITH EXECUTE AS CALLER
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Return varchar(500)

    BEGIN TRY

    SELECT  @Name = Name 
    FROM [dbo].Table1
    WHERE ID = @ID

    --bunch of IF ELSE Statements...

        BEGIN
            EXEC dbo.GoalStop  @ID, @StopDate --Call to other stored procedure
            INSERT INTO [dbo].Table1([Name], [Goal], [StartDate], [StopDate], [Updatedby], [UpdateDate])
            VALUES (@Name, @Goal, @StartDate, @StopDate, @Updatedby, @UpdateDate)

            SET @Return = 'The Goal was successfully created.';             
         END
     END

     SELECT 'DATABASE MESSAGE: ' + @Return

    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK

        DECLARE @ErrMsg VARCHAR(4000), @ErrSeverity INT
        SELECT @ErrMsg  =  ERROR_MESSAGE(), @ErrSeverity = ERROR_SEVERITY()
        RAISERROR(@ErrMsg, @ErrSeverity, 1)
    END CATCH
END

Output of stored procedure in query analyzer

和调用此过程的C#代码:

string returnString = string.Empty;
SqlDataReader reader;

try
{
    using (SqlConnection connection = Connection.GetSqlConnection())
    {
        using (SqlCommand command = new SqlCommand("dbo.Goal_Restart", connection))
        {
            command.CommandType = CommandType.StoredProcedure;
            command.CommandTimeout = 90;

            command.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
            command.Parameters.Add("@Goal", SqlDbType.Decimal).Value = goal;
            command.Parameters.Add("@Updatedby", SqlDbType.Char, 7).Value = Updatedby;
            command.Parameters.Add("@UpdateDate", SqlDbType.DateTime).Value = updateDate;

            if (startDate != null)
            {
                command.Parameters.Add("@StartDate", SqlDbType.DateTime).Value = startDate;
            }

            if (stopDate != null && (Convert.ToDateTime(stopDate)).ToShortDateString() != "1/1/1900")
            {
                command.Parameters.Add("@StopDate", SqlDbType.DateTime).Value = stopDate;
            }

            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }

            command.Prepare();
            reader = command.ExecuteReader();

            while (reader.Read())
            {
                returnString = reader[0].ToString();
            }
        }
    }
}

如果我在查询分析器中执行,则输出是两个差异查询的结果(请参见附图)

DATABASE MESSAGE: The Goal was successfully Stopped.
DATABASE MESSAGE: The Goal was successfully created.

然而,C#中的returnString仅捕获来自嵌套过程的消息而不是调用过程。

DATABASE MESSAGE: The Goal was successfully Stopped.

如何捕获两个或仅捕获调用过程?

1 个答案:

答案 0 :(得分:1)

正如您使用SqlDataReaderReader.Read光标到下一行一样,您还必须使用SqlDataReader.NextResult()转移到下一个 结果集

while (reader.Read())
{
    //Do something with first resultset
}
var ok = reader.NextResult();
if (ok)
{
    while (reader.Read())
    {
        //Do something with outer proc's resultset  
    }
}