使用 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 / 在另一个查询中重用存储过程的结果