使用存储过程的结果加入表
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 没有很好的解决方案,但很有可能成为可能。以上是关于使用存储过程的结果加入表的主要内容,如果未能解决你的问题,请参考以下文章