我有一个存储过程,它根据成功或失败返回两个结果集。
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,所以我需要在临时表中做一些事情(不确定)来处理失败和成功。
答案 0 :(得分:1)
您无法返回2个不同的记录集并加载相同的临时表。 也不能尝试填写2个不同的表格。
有两种选择。
修改存储过程
如果您使用的是SQL Server 2005,请使用TRY / CATCH分隔您的成功和失败代码路径。下面的代码依赖于使用新的错误处理来通过异常/ RAISERROR传回错误结果集。
示例:
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中的正确答案。