【问题标题】:Efficient multiple selects in a single stored proc在单个存储过程中进行高效的多项选择
【发布时间】: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


【解决方案1】:

我认为这里最好的方法是使用 CTE(通用表表达式)。

语法是

;With CTE as
(
   Select ...
)

您的查询应该是这样的......

;WITH @Result AS
(
   SELECT 
     ID, 
     col2, 
     col3, ...
   FROM 
    dbo.Orders
   WHERE x=y
)
SELECT 
  ID, 
  OrderID, 
  col3,
  col4
FROM 
  dbo.OrderItems I
INNER JOIN
  @Result
ON
  @Result.ID   = I.OrderID
ON

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2016-07-03
    • 2010-11-29
    相关资源
    最近更新 更多