使用 SQL 获取在另一个中调用的一个存储过程的输出

Posted

技术标签:

【中文标题】使用 SQL 获取在另一个中调用的一个存储过程的输出【英文标题】:Getting output of one Stored Procedure called in another using TSQL 【发布时间】:2020-03-04 19:36:40 【问题描述】:

我有两个存储过程 spParent 和 spParentChild。 spParent 调用 spParentChild。遵循 SP:

CREATE PROCEDURE [dbo].[spParent]
        @isApproved varchar(max) = 'TEST',
        @ApplicationDBName varchar(100) = 'secDB',
        @ApplicationInsertSPName varchar(100) = 'spParentChild',
        @resultP varchar(max) output
AS
BEGIN
    BEGIN TRY
        SET NOCOUNT ON;
        IF @resultP <> ''
        BEGIN
            RAISERROR('An error occurred in the parent SP.', 18, 0)
        END

        DECLare @resultCC varchar(max)
        DECLARE @SP_Call Varchar(MAX)
        SET @SP_Call = 'exec spParentChild ''1'', @resultCC output'
        EXEC @SP_Call 
        select @resultCC
    END TRY
    BEGIN CATCH
        Declare @ErrMessage Varchar(max)
        Declare @ErrState Varchar(max)
        Declare @ErrLine Varchar(max)

        select @ErrMessage=ErrorMessage, @ErrLine=ErrorLine, @ErrState=ErrorState  from fnGetError()

        IF @ErrMessage is not Null
        BEGIN
            SELECT @resultP = @ErrMessage
            SELECT @resultCC
        END
        ELSE
        BEGIN
            SELECT @resultP = 'An unknown error occurred.'
            raiserror(@resultP,18,0)
        END
    END CATCH
END

CREATE PROCEDURE [dbo].[spParentChild]
        @isApproved varchar(max) = 'TEST',
        @resultC varchar(max)   output  
AS
BEGIN
    BEGIN TRY
        SET NOCOUNT ON;
        RAISERROR('An error occurred in the child SP.', 18, 0)
    END TRY
    BEGIN CATCH
        Declare @ErrMessage Varchar(max)
        Declare @ErrState Varchar(max)
        Declare @ErrLine Varchar(max)

        select @ErrMessage=ErrorMessage, @ErrLine=ErrorLine, @ErrState=ErrorState  from fnGetError()

        IF @ErrMessage is not Null
        BEGIN
            SET @resultC = @ErrMessage
        END
        ELSE
        BEGIN
            SELECT @resultC = 'An unknown error occurred.'
        END
    END CATCH
END

如您所见,spParent 调用 spParentChild。我需要的是使用 TSQL 进行调用,但它不起作用。如果我使用以下一切正常,但我需要 TSQL:

EXEC spParentChild 1, @resultCC output

谁能帮我看看我做错了什么,或者这是否可能?

提前谢谢你。

戈弗雷

【问题讨论】:

为什么是SET @SP_Call = 'exec spParentChild ''1'', @resultCC output' ;EXEC @SP_Call;?就做exec spParentChild ''1'', @resultCC output; 不需要“动态”声明。 另外,EXEC @SP_Call 将转换为 EXEC EXEC ...,这显然会失败。 抱歉,实际的 TSQL 中没有 exec。我要更改的 SP 要复杂得多,需要 TSQL。 以上都是T-SQL,@Jeff,但是你的语句不是动态的,所以不需要动态语句。 我刚刚意识到我的问题之一是@resultCC 不是 exec 语句的本地。我要更改的 SP 有大量用于传递到另一个数据库的 XML。 XML 是从传入的变量构建的。我认为这是不可能的。我感谢大家的时间。高度赞赏。 【参考方案1】:

对于那些有类似问题或需要的人,我发布了我整理的这个解决方案。这听起来好像很疯狂,但是当我告诉你我确实需要这个并且需要这个的实际 SP 太长而无法发布时,请相信。

spParentChild 没有改变,保持如上。 spParent 更改如下所示。结果是 spParent 调用 spParentChild。在他的情况下,如果 spParentChild 发生错误,则消息将在输出参数中传递给 spParent。

如果您有任何问题,我将尝试回答。以下是spParent:

ALTER PROCEDURE [dbo].[spParent]
        @isApproved varchar(max) = 'TEST',
        @ApplicationDBName varchar(100) = 'SecDB',
        @ApplicationInsertSPName varchar(100) = 'spParentChild',
        @resultP varchar(max) output
AS
BEGIN
    BEGIN TRY
        SET NOCOUNT ON;
        IF @resultP <> ''
        BEGIN
            RAISERROR('An error occurred in the parent SP.', 18, 0)
        END

        DECLARE @params NVarChar(max)
        SET @params = '@resultCC VarChar(100) OUTPUT' -- OUTPUT Parameter for the called child SP
        DECLARE @SP_Call NVarchar(MAX) -- sp_executesql requires NVarChar
        SET @SP_Call = '[' + @ApplicationDBName + '].[dbo].[' + @ApplicationInsertSPName + '] ' + ' ''1'', @resultCC OUTPUT' -- ResultCC is the output parameter for the sp_executesql
        EXEC sp_executesql @SP_Call, @params, @resultCC = @resultP OUTPUT -- Assign the value to the output parameter of this SP

        -- EXEC spParentChild 1, @resultCC output -- THE ABOVE 5 LINES OF CODE ARE EQUAL TO THIS IS A HARDCODED CALL
        if @resultP <> ''
        BEGIN
            SELECT @resultP [Returned Value]
        END

    END TRY
    BEGIN CATCH
        Declare @ErrMessage Varchar(max)
        Declare @ErrState Varchar(max)
        Declare @ErrLine Varchar(max)

        select @ErrMessage=ErrorMessage, @ErrLine=ErrorLine, @ErrState=ErrorState  from fnGetError()

        IF @ErrMessage is not Null
        BEGIN
            SELECT @resultP = @ErrMessage
            SELECT @ErrMessage
        END
        ELSE
        BEGIN
            SELECT @resultP = 'An unknown error occurred.'
            SELECT 'bbb'
            raiserror(@resultP,18,0)
        END
    END CATCH
END

我希望这可以帮助有这种需要的人。

【讨论】:

以上是关于使用 SQL 获取在另一个中调用的一个存储过程的输出的主要内容,如果未能解决你的问题,请参考以下文章

Informix SQL / 在另一个查询中重用存储过程的结果

在另一个过程中调用sql过程

如何在另一个存储过程中调用一个存储过程(PHP 和 mysqli)

在另一个存储过程中调用时是否抑制存储过程输出?

在另一个存储过程中调用时抑制存储过程输出?

在另一个具有动态查询的存储过程中使用具有动态查询的存储过程的结果