TSQL-游标中返回的空行

时间:2018-09-06 16:49:12

标签: sql-server tsql sql-update cursor no-data

抱歉,这可能是一个非常愚蠢的问题-我正在使用游标,它将一个约有697K行的临时表和一个返回78K行的函数连接在一起。 (我应该添加的一项改进是它以前会更糟)。光标经过并匹配两个“表”中的两个值,并更新第三个值。这需要6个小时左右。这是荒谬的。我们正在尝试提出提高效率的方法。

任何人和所有建议都将受到赞赏。但我的询问是这个

enter image description here

似乎正在返回看起来如下的数据(在许多情况下为空信息)。我可以将代码限制为在何处...数据不为null ...但不是返回值。null为空/不存在的行。我在想是否有办法排除这样的行,我们可能会限制我们的数据池。但是我并不完全知道这意味着什么。

declare @season int = 21

DECLARE @match varchar(55)
declare @perf_no int
declare @order_dt datetime

DECLARE   @price CURSOR
SET       @price = CURSOR FOR
SELECT    distinct match_criteria, perf_no, order_dt
FROM      #prices
OPEN      @price
FETCH NEXT
FROM      @price INTO @match, @perf_no, @order_dt
WHILE     @@FETCH_STATUS = 0
BEGIN

select  @match, @perf_no, @order_dt, x.price as 'amount'
from    #prices p
join    dbo.[LFT_GET_PRICES_Seasonal] (@season, @order_dt) x on p.perf_price_type = x.perf_price_type and p.zone_no = x.zone_no
where   match_criteria = @match and perf_no = @perf_no

FETCH NEXT
FROM @price INTO @match, @perf_no, @order_dt
END
CLOSE @price
DEALLOCATE @price

这里是#prices和#我们的函数返回的值的示例。

价格

pkg_no  perf_no zone_no price_type  order_dt                    price   perf_price_type match_criteria
12      144     2707    1073        2018-09-03  00:00:00.000    NULL    115769          O5716788P1517Z2707
12      123     2707    1073        2018-09-03  00:00:00.000    NULL    115840          O5716788P1517Z2707
12      887     2707    1073        2018-09-03  00:00:00.000    NULL    115521          O5716788P1517Z2707

功能:

perf_price_type zone_no price   min_price   enabled editable_ind
115521          2678    12.00   12.00       Y       N
115521          2679    61.00   61.00       Y       N
115521          2680    41.00   41.00       Y       N

游标所做的是根据该函数的价格更新#prices表中的价格。 (我们使用光标仅将其限制为某些性能/限制条件)。但我愿意提出建议。以及关于如何改善这一点的建议。

1 个答案:

答案 0 :(得分:0)

您写的是要使用表值函数的结果更新#price表。
您可以使用cross apply代替光标来做到这一点。 由于您没有发布正确的样本数据,所以我无法测试我的答案,但是如果它满足您的要求,那么与光标相比,它应具有闪电般的快速性。

DECLARE @season int = 21

UPDAET p
SET price = x.Price
FROM #Prices p
CROSS APPLY  
(
    SELECT * 
    FROM dbo.LFT_GET_PRICES_Seasonal(@season, order_dt) udf
    WHERE udf.perf_price_type = p.perf_price_type 
    AND udf.zone_no = p.zone_no
) x

SQL使用基于集合的方法而不是过程方法的效果最佳,这就是为什么要尽可能避免循环和游标,而仅将它们用作最后​​的选择。