如何检查被调用存储过程的输出 table?

How to check for output table of called stored procedure?

简单的场景。存储过程 sp_Task1 调用 sp_Task2sp_Task2 有一个名为 #Task2_Output 的输出临时 table。我希望 sp_Task1 接受 #Task2_Output 并用它执行进一步的交易。

如何让这两件事发生:

1) 确保 sp_Task1 等到 sp_Task2 完成后才转到下一行代码。

2) 如何从 sp_Task1.

中的代码检查 #Task2_Output 是否成功创建

你不说是哪个DBMS,我假设是SQL服务器,因为这种情况经常出现在那里。

对于问题 1:

在 SQL Server 2005 中,要使调用存储过程可以访问临时 table,您可能必须使用 ##Task2_Output(没错,两个哈希值)而不是 #Task2_Output,因为带有两个 # 前缀的临时 table 名称有点像全局临时 table,可用于调用过程,但在最后一次使用后被销毁。但是,如果 table 名称不是动态分配的,您可能需要注意名称冲突。

对于问题 2 :

获取sp_Task2到return一个Return代码,带有RETURN语句。 如果 table 创建成功,比如 Return 1。 如果 table 创建失败(通过在语句后立即检查 @@ERROR 知道),那么,比如说,Return -99。

在 sp_Task1 中,像下面这样调用 sp_Task2 :

Declare @MyRetCode_Recd_In_Task1 int

EXECUTE @MyRetCode_Recd_In_Task1 = sp_Task2 (with calling parameters if any). 

使用 ReturnCode = StoredProcName 方式调用存储过程,sp_Task1 接收 sp_Task2 编辑的 return 代码 return。然后您可以检查 sp_Task1 中的 return 代码,看看是否一切正常。

接受的答案不正确。

对于问题 1:

Make sure sp_Task1 waits until sp_Task2 is completed to move on to the next line of code.

您无需执行任何操作。调用存储过程和函数不是异步的。如果 sp_Task1 中有以下内容:

... other SQL commands

EXEC sp_Task2;

... more SQL commands

然后 "more SQL commands" 将不会执行,直到 sp_Task2; 完成(无论是成功还是由于错误)。

对于问题 2:

How to check that #Task2_Output was successfully created from code within sp_Task1

如前所述,在子流程中创建的本地临时tables(即前缀=#)将在该子流程(即调用sp_Task2) 结束。您 可以 使用全局临时 table (即前缀 = ##),但是 sp_Task1 只能由一个 session/connection 调用一次,否则您将 运行 陷入 ##Task2_Output 上的名称冲突。但这可以通过简单地在 sp_Task1 中创建本地临时文件 table 来轻松避免。必须知道该临时文件 table 的名称,因为它将在 sp_Task2 完成后在 sp_Task1 中访问。所以没有理由不先创建它:

CREATE TABLE #Task2_Output (columns...);

... other SQL commands

EXEC sp_Task2;

... more SQL commands

SELECT ...
FROM   #Task2_Output;

然后你就不需要测试了。


另外:

  • 如果您确实想测试临时文件是否存在 table,请使用以下命令:

    IF (OBJECT_ID(N'tempdb..#Task2_Output') IS NOT NULL)
    BEGIN
      -- non-NULL value from OBJECT_ID() means the table exists
      ..do something;
    END;
    
  • 你真的、真的应该在存储过程名称前加上sp_。该前缀是为系统进程保留的,由 SQL 服务器作为特殊情况处理。它将首先在 [master] 数据库中检查该过程,然后在本地或指定的数据库中检查。因此这是不必要的性能损失。

  • 而不是使用@@ERROR,使用TRY / CATCH结构更有效。