使用存储过程的结果加入表

Posted

技术标签:

【中文标题】使用存储过程的结果加入表【英文标题】:Use result of stored procedure to join to a table 【发布时间】:2016-09-07 19:26:26 【问题描述】:

我有一个存储过程,它从动态数据透视查询返回数据集(这意味着数据透视列直到运行时才知道,因为它们是由数据驱动的)。

此数据集中的第一列是产品 ID。我想将该产品 ID 与另一个产品表连接起来,该表具有在设计时创建的各种其他列。

所以,我有一个带有产品 id 列的普通表,并且我有一个“动态”数据集,该数据集还有一个产品 id 列,我通过调用存储过程获得。我怎样才能加入那两个?

【问题讨论】:

从 SP 输出创建一个临时表,如 here 所示,并像往常一样将您的表与临时表连接 因为我不知道架构,唯一的方法是可能有严重的安全风险? 存在明显风险;您可能需要权衡您的解决方案与需求;可能有一种不同的方法完全避免动态透视输出加入表 How can I join on a stored procedure?的可能重复 【参考方案1】:

Dynamic SQL 非常强大,但也有一些严重的缺点。其中之一就是这样:您不能在 ad-hoc-SQL 中使用它的结果。

将 SP 的结果放入表中的唯一方法是创建具有合适架构的表并使用 INSERT INTO NewTbl EXEC... 语法...

但还有其他可能性:

1) 使用SELECT ... INTO ... FROM

在您的 SP 中,当动态 SQL 被执行时,您可以将 INTO NewTbl 添加到您的选择中:

SELECT Col1, Col2, [...] INTO NewTbl FROM ...

这将自动创建一个具有合适架构的表。

您甚至可以将新表的名称作为参数提交 - 因为它是动态 SQL,但在这种情况下,处理外部连接会更加困难(必须再次是动态的)。

如果您需要您的 SP 返回结果,您只需添加 SELECT * FROM NewTbl。这将返回与以前相同的结果集。

在你的 SP 之外你可以像任何普通的表一样加入这个表...

但是,有一个很大的 BUT - ups - 这听起来很讨厌 - 如果表存在,这将失败......

所以你必须先放弃它,如果这是一个可能并发的多用户应用程序,这可能会导致严重的麻烦。

如果不是:使用IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='NewTbl') DROP TABLE NewTbl;

如果是:使用您作为参数传入的名称创建表,并使用此名称动态进行外部查询。

之后,您可以使用SELECT ... INTO 语法重新创建此表...

2) 使用 XML

XML 的一个优点是,任何结构和任何数量的数据都可以填充到单个列中。

让您的 SP 返回一个包含一个 XML 列的表。您可以 - 正如您现在所知道的架构一样 - 创建一个表并使用 INSERT INTO XmlTable EXEC ...

知道会有一个ProductID-元素,您可以提取此值并使用 ID 和相关 XML 创建一个 2-column-derived-table。这很容易加入。

在 XQuery 中使用通配符可以在不知道所有细节的情况下查询 XML 数据...

3) 这是我最喜欢的:不要使用动态查询...

【讨论】:

感谢您的选择。我是一个业务第一的人,我从不喜欢限制业务或需求,因为技术可能无法完全解决业务问题,所以选项 3 不是我最喜欢的。我喜欢突破界限,我知道这可能会带来问题。 :) 我认为这是一个技术问题,SQL Server 没有很好的解决方案,但很有可能成为可能。

以上是关于使用存储过程的结果加入表的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程 中把临时表数据 返回结果集

oracle 存储过程,数据处理并返回结果集问题

如何在存储过程中直接使用另一个存储过程返回的数据集

MYSQL 存储过程如何取得一个表的查询结果?

将存储过程结果插入临时表

如何在 spring 中使用 SimpleJDBCCall 获取存储过程的结果以及两个结果表?