从另一个存储过程调用的存储过程中获取第一个结果集

Posted

技术标签:

【中文标题】从另一个存储过程调用的存储过程中获取第一个结果集【英文标题】:grabbing first result set from a stored proc called from another stored proc 【发布时间】:2009-06-12 18:17:56 【问题描述】:

我有一个 SQL Server 2005 存储过程,它返回两个架构不同的结果集。

另一个存储过程将其作为 Insert-Exec 执行。但是我需要插入第一个结果集,而不是最后一个。有什么方法可以做到这一点?

我可以创建一个新的存储过程,它是第一个存储过程的副本,它只返回我想要的结果集,但我想知道我是否可以使用返回两个的现有存储过程。

【问题讨论】:

Access to Result sets from within Stored procedures Transact-SQL SQL Server的可能重复 【参考方案1】:

实际上,INSERT..EXEC 会尝试将 BOTH 数据集插入到表中。如果列数匹配并且可以隐式转换数据类型,那么您实际上会得到两者。

否则,它总是会失败,因为没有办法只获得其中一个结果集。

解决此问题的方法是从被调用过程中提取您想要的功能并将其合并到(以前的)调用过程中。并且在做的时候提醒自己“SQL不像客户端代码:冗余代码比冗余数据更容易接受”。

如果上面不清楚,让我描述一下在这种情况下任何人都可以使用的事实和选项:

1) 如果返回的两个结果集是兼容的,那么您可以使用 INSERT 将两者放在同一个表中,并尝试删除您不想要的。

2) 如果两个结果集不兼容,则 INSERT..EXEC 无法工作。

3) 可以将代码从被调用过程中复制出来,在调用者中重复使用,并承担双重编辑维护的成本。

4) 您可以更改被调用的过程,使其与您的其他过程更兼容。

就是这样。对于这种情况,这些是您在 T-SQL 中的选择。您可以使用 SQLCLR 或客户端代码玩一些额外的技巧,但它们会涉及到一些不同的处理方式。

【讨论】:

我知道这一点,就像我说的,这两个结果集有模式。所以不,两者都不能插入同一个表中。我需要按照我解释的方式进行操作,这样如果有人修改了第一个 proc,第二个 proc 会自动获取第一个 proc 返回的正确数据。复制 sql 不是一个好主意,因为开发人员必须同时修改两者,开发人员会错过依赖关系。这不是一个冗余数据案例。这是不好的冗余代码。 请重新阅读我的答案,您提出的所有内容都包含在此处:1)您不能只获得其中一组,2)它们必须是相同的模式才能获得两者,3 )没有办法解决这个问题,4)你最好的选择是复制代码。唯一的另一种选择是将调用的过程更改为更兼容。这些是您唯一的选择。抱歉,SQL 就是这样工作的。【参考方案2】:

你不能让第一个存储过程只返回一个结果集,有什么令人信服的理由吗?通常,您应该避免让一个存储过程同时执行 INSERT 和 SELECT(如果 SELECT 是为了获取新创建的行的标识,则例外)。

【讨论】:

第一个 sproc 是现有的,并且已经在生产中。至于你提到的规则,sproc 做它需要做的任何事情都没有错。在一个存储过程中进行多次插入和选择是很常见的。你没有解释有什么缺点。【参考方案3】:

为了防止代码在两个进程之间不同步,为什么不编写一个 proc 来执行您想要的插入操作,在您的进程中调用它并让原始 proc 调用它来获取第一个记录集和然后做它需要做的任何其他事情。

根据您获得此选择的方式,它可能会被重构为表值函数,而不是两个进程都会调用的 proc。

【讨论】:

原始过程不能也不应该为此目的而改变。这是一个复杂的,不应该仅仅因为另一个 proc 想要相同的数据而被触及。我不想复制代码的原因是它有一英里长,如果我可以在我的 proc 中的单个语句中调用它会非常方便。如果有的话,我必须想出一个解决方案,在不修改的情况下重复使用它。

以上是关于从另一个存储过程调用的存储过程中获取第一个结果集的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 从另一个存储过程调用存储过程

在 Oracle 中从另一个存储过程调用一个存储过程

从另一个存储过程调用具有交叉应用的存储过程会产生错误 SQL 服务器

如何传递逗号分隔的输入参数以从另一个存储过程调用存储过程

MySQL 存储过程,获取使用游标查询的结果集

如何在没有临时表的情况下从另一个存储过程调用存储过程(带参数)