基于成功或失败的结果集

时间:2009-04-12 09:18:42

标签: sql-server stored-procedures temp-tables

我有一个存储过程,它根据成功或失败返回两个结果集。

SP成功结果集:name,id,error,desc
SP失败结果sret:错误,desc

我正在使用以下查询来获取存储过程的结果。成功返回0,失败返回-1。

declare @ret int

DECLARE @tmp TABLE (
     name  char(70),
     id    int,
     error char(2),
     desc  varchar(30)
)

insert into @tmp
EXEC @ret  = sptest '100','King'

select @ret

select * from @tmp

如果SP成功,则由于列匹配,因此将四个字段插入到临时表中。 但是如果失败,sp结果集只有error和desc,它与temp表中没有列匹配... 。我无法改变Sp,所以我需要在临时表中做一些事情(不确定)来处理失败和成功。

4 个答案:

答案 0 :(得分:1)

您无法返回2个不同的记录集并加载相同的临时表。 也不能尝试填写2个不同的表格。

有两种选择。

  1. 修改存储过程

    • 所有条件下都会返回所有4列
    • 第一对(名称,ID)列在出错时为NULL
    • 第二对(错误,desc)成功时为NULL
  2. 如果您使用的是SQL Server 2005,请使用TRY / CATCH分隔您的成功和失败代码路径。下面的代码依赖于使用新的错误处理来通过异常/ RAISERROR传回错误结果集。

  3. 示例:

    CREATE PROC sptest
    AS
    DECLARE @errmsg varchar(2000)
    
    BEGIN TRY
       do stuff
       SELECT col1, col2, col3, col4 FROM table etc
       --do more stuff
    END TRY
    BEGIN CATCH
       SELECT @errmsg = ERROR_MESSAGE()
       RAISERROR ('Oops! %s', 16, 1, @errmsg)
    END CATCH
    GO
    
    DECLARE @tmp TABLE ( name CHAR(70), id INT, error char(2), desc varchar(30)
    
    BEGIN TRY
        insert into @tmp
        EXEC sptest '100','King'
        select * from @tmp
    END TRY
    BEGIN CATCH
       PRINT ERROR_MESSAGE()
    END CATCH
    

答案 1 :(得分:0)

我的错!! 答案太快了。 您只需要重新设置返回值,因此构建逻辑更好。

如果你仍然想使用临时表,那么调用sptest两次可能是一种处理它的方法(尽管不是最佳的),一次获得返回值并基于它然后有2个不同的临时表你填满(一个是4个字段,另一个是2个字段)。

declare @ret int

DECLARE @tmp TABLE (name CHAR(70), id INT, error char(2), desc varchar(30))
DECLARE @tmperror TABLE (error char(2), desc varchar(30))


EXEC @ret = sptest '100','King'

IF @ret != 0
BEGIN
  INSERT INTO @tmperror
  EXEC sptest '100','King';
  SELECT * FROM @tmperror;
END
ELSE
BEGIN
  INSERT INTO @tmp
  EXEC sptest '100','King';
  SELECT * FROM @tmp;
END

请记住,此解决方案并非最佳。

答案 2 :(得分:0)

尝试修改表定义,以便前两列可以为空:

DECLARE @tmp TABLE (
 name  char(70) null,
 id    int null,
 error char(2),
 desc  varchar(30)

希望这有帮助,

比尔

答案 3 :(得分:0)

只用一个电话就无法做到这一点。您必须调用一次,获取返回状态,然后根据INSERT..EXEC命令的状态进行分支,该命令将用于将返回的列数或调用一次,假设成功,则使用TRY。 .CATCH,然后在Catch中再次调用它,假设它将失败(这是它到达CATCH的方式)。

更好的方法是重写存储过程,使其返回一致的列集,或者通过从该存储过程中提取代码并对其进行调整来编写自己的存储过程,表值函数或查询。给你使用这是SQL中的正确答案。