【问题标题】:How to consolidate results from multiple invocations of a stored procedure?如何合并存储过程的多次调用的结果?
【发布时间】:2017-07-05 08:11:52
【问题描述】:

我有一个应该按如下方式工作的存储过程:

DECLARE @TagNames AS TABLE
(
    tag NVARCHAR(50) NOT NULL
)

-- Get list of tags
INSERT INTO @TagNames
SELECT tag
FROM tagTable
WHERE tag LIKE @tagPattern

-- Create unified result set, combining results from stored proc for each tag
SELECT n.tag, r.time, r.value FROM @TagNames AS n
CROSS APPLY
    dbo.GetResultsForTag(n.tag) AS r -- Not valid

但是,我不能使用 CROSS APPLY,因为 dbo.GetResultsForTag() 是一个存储过程。

dbo.GetResultsForTag() 的实现依赖于在传递给链接服务器的动态 SQL 上调用EXEC,所以我相信它不能转换为表值函数。表值函数中不允许使用动态 SQL。

链接服务器通过 OLE-DB 提供程序进行通信,但它不是 SQL Server 实例。这是一个 OSISoft PI 过程历史数据库。通常,在单个查询中查询多个数据标签非常容易,但在这种情况下,我正在做一些计算,这需要我提供一个指定单个标签名称的过滤器表达式。所以每个标签都需要单独查询数据源。

据我所知,存储过程不能用作 JOIN 的右侧?

我还有哪些其他选择可以将这些结果整合在一起?只是一个光标?


编辑:我已经弄清楚了如何解决迫使我使用动态 SQL 和存储过程的潜在障碍。现在我可以使用常规 SQL,它允许我使用表值函数而不是存储过程,这允许我使用 JOIN 和 CROSS APPLY 而不是丑陋的游标黑客。

【问题讨论】:

  • 您使用的 SQL Server 版本是什么?
  • SQL Server 2016 标准版
  • 看起来我可能会使用光标来遍历标签列表。或者,标签列表将只包含 7 个项目,所以也许我可以将它们作为单独的参数传递,并静态调用 EXEC dbo.GetResultsForTag 7 次。这两种解决方案看起来都很难看。

标签: sql-server stored-procedures sql-server-2016


【解决方案1】:

将存储过程重写为表值函数??

或者,重新编写它以取消过滤器,将其转储到一个表(可能是一个临时表),然后加入该表。

【讨论】:

  • 我不相信我可以把它写成表值函数,因为我需要使用动态 SQL 来构造远程数据源上的查询。我也无法从远程查询中删除标记名过滤器,因为没有它远程查询无效。
  • 为什么不在计时器上进行远程查询,将所有标签拉入 SQL,然后对该数据执行连接/TVF... 进行远程查询没有意义每次
  • GetResultsForTag 存储过程要求 PI 服务器对其原始数据执行计算并将结果返回给我。由于远程查询处理器的设计,我一次只能为一个标签执行此操作 - 基本上,我使用的功能要求我将过滤器表达式作为字符串值传递,并且该表达式还包括标签名称.我宁愿不通过网络移动(大得多的)原始数据或在我的最后重新实现计算。
  • 不能在你的应用层做这个吗?在数据库级别执行此操作听起来是个糟糕的主意......
  • 不太容易 - 我可以通过各种方式配置应用程序,但不能编辑其源代码。它包括从 SQL 语句或存储过程调用中读取结果集的功能,因此我正在尝试编写一个存储过程来生成单个结果集供应用程序使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 2012-01-29
  • 1970-01-01
相关资源
最近更新 更多