【发布时间】:2011-06-27 10:06:36
【问题描述】:
我需要创建一个返回两个结果集的存储过程。第二组包含通过父/子关系与第一组中的记录相关的记录。
例如,第一条语句返回订单:
SELECT ID, col2, col3, ...
FROM dbo.Orders
WHERE x=y
第二个语句返回这些订单的单个项目:
SELECT ID, OrderID, col3, col4, ...
FROM dbo.OrderItems
WHERE OrderID IN (<IDs from first statement>)
我正在寻找实现这一目标的最有效方法。目前我的解决方案如下所示:
-- create a table variable to hold results from first statement
DECLARE @Result TABLE
(
ID int NOT NULL,
col2 nvarchar(50),
col3 nvarchar(50)
)
-- select orders
INSERT INTO @Result (ID, col2, col3)
SELECT ID, col2, col3, ...
FROM dbo.Orders
WHERE x=y
SELECT * FROM @Result
-- select order items corresponding to the orders in the @Result table
SELECT ID, OrderID, col3, col4
FROM dbo.OrderItems I
INNER JOIN @Result R ON R.ID = I.OrderID
这似乎工作得很好。然而,要求是第一个语句中的 WHERE 子句变得非常复杂,并且适合使用 CTE(WITH 语句),但是同时具有 WITH 和表变量会变得非常复杂。有什么更好的方法来解决这个问题?
【问题讨论】:
-
我认为 CTE 和表变量的组合没有任何问题。我们正在使用它,我没有发现任何问题。
-
单个结果集怎么样?
-
@TcKs:我确信它会起作用,但我认为它不是很优雅。如果没有更好的建议,我一定会使用它。
-
@gbn:第二个结果集包含与第一个不同的列。这两个结果集在业务层中被“组装”成具有相同父/子关系的对象。使用单个结果集将需要返回大量不必要的空字段,以及将正确的字段映射到业务层中的对象属性的更多逻辑。
-
无法通过单个 SELECT 语句返回多个结果集。因此,您可以在同一张表上使用相似的 JOIN/WHERE 执行两个 SELECT,或者您必须使用 tabler-variable/temporary-table。没有灵丹妙药的解决方案,如果您想要适合您的情况的最佳解决方案,您可以尝试使用生产数据并测量性能(内存使用情况、选择时间、表锁等)的所有方法。但是根据我使用表变量的经验,一般来说是很好的解决方案。
标签: sql stored-procedures select