基于成功或失败的结果集

发布于 2024-07-17 08:50:37 字数 507 浏览 6 评论 0原文

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

SP成功结果集: name, id ,error,desc
SP 失败结果 sret: error,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 结果集只有错误和 desc,与临时表中的列不匹配... .我无法更改 Sp,所以我需要在临时表中做一些事情(不确定)来处理失败和成功。

I'm having a stored procedure which returns two result sets based on the success or failure.

SP success result set: name, id ,error,desc
SP failure result sret: error,desc

I'm using the following query to get the result of the stored procedure. It returns 0 for success and -1 for failure.

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

If the SP is success the four field gets inserted into the temp table since the column matches.
But in case of failure the sp result set has only error and desc which does not matchs with no of columns in the temp table...
.I can't change the Sp, so I need to do some thing (not sure) in temp table to handle both failure and success.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乖乖哒 2024-07-24 08:50:37

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

有 2 个选项。

  1. 修改您的存储过程

    • 在所有条件下都会返回所有 4 列
    • 第一对(名称、ID)列出错时为 NULL
    • 成功时第二对(错误、描述)为 NULL
  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

You can't return 2 different recordsets and load the same temp table.
Neither can try and fill 2 different tables.

There are 2 options.

  1. Modify your stored proc

    • All 4 columns are returned in all conditions
    • 1st pair (name, ID) columns are NULL on error
    • 2nd pair (error, desc) are NULL on success
  2. If you are using SQL Server 2005 then use the TRY/CATCH to separate your success and fail code paths. The code below relies on using the new error handling to pass back the error result set via exception/RAISERROR.

Example:

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
飞烟轻若梦 2024-07-24 08:50:37

我的错!!
回答得太快了。
您只需要关注返回值,因此针对它构建逻辑要好得多。

如果您仍然想使用临时表,那么调用 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

请记住,此解决方案不是最佳的。

My fault!!
Was too quick in the answer.
You need only to relv on the return value, so building up the logic against it is much better.

If you still want to use the temp table, then calling the sptest twice could be a way to deal with it (not optimal though), one time to get the return value and based on it then have 2 different temp tables you are filling up (one would be with the 4 fields, the other only with 2 fields).

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

Keep in mind that this solution is not optimal.

俯瞰星空 2024-07-24 08:50:37

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

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

:)

希望这会有所帮助,

比尔

Try modifying your table definition so that the first two columns are nullable:

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

)

Hope this helps,

Bill

久隐师 2024-07-24 08:50:37

您无法仅通过一个电话来完成此操作。 您必须调用它一次,要么获取返回状态,然后根据 INSERT..EXEC 命令的状态进行分支,该命令将适用于将返回的列数,要么使用 TRY 调用一次(假设成功)。 .CATCH,然后在 Catch 中再次调用它,假设它会失败(这就是它到达 CATCH 的方式)。

更好的是,要么重写存储过程,以便它返回一致的列集,要么编写您自己的存储过程、表值函数或查询,方法是从此存储过程中提取代码并根据您的使用进行调整。 这是 SQL 中的正确答案。

You cannot do this with just one call. You will have to call it once, either getting the return status and then branching depending on the status to the INSERT..EXEC command that will work for the number of columns that will be returned or Call it once, assuming success, with TRY..CATCH, and then in the Catch call it again assuming that it will fail (which is how it got to the CATCH).

Even better, would be to either re-write the stored procedure so that it returns a consistent column set or to write you own stored procedure, table-valued function or query, by extracting the code from this stored procedure and adapting it to your use. This is the proper answer in SQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文