Sql 避免在UPDATE语句中多次调用标量函数

Sql 避免在UPDATE语句中多次调用标量函数,sql,sql-server,tsql,Sql,Sql Server,Tsql,有没有办法修改下面的UPDATE语句,使标量函数只调用一次,而不是两次 UPDATE a SET SomeField = b.SomeField FROM TableA AS a JOIN TableB b ON b.Link = a.Link WHERE b.CostMin <= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency) AND b.CostMax >= @Cos

有没有办法修改下面的
UPDATE
语句,使标量函数只调用一次,而不是两次

UPDATE a
    SET SomeField = b.SomeField
    FROM TableA AS a
    JOIN TableB b ON b.Link = a.Link
    WHERE b.CostMin <= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)
        AND b.CostMax >= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)
更新a
设置SomeField=b.SomeField
从表a作为
在b.Link=a.Link上连接表b
其中b.CostMin=@Cost*dbo.OneScalarFunction(@CurrencyFrom,b.Currency)

p.S.使用
BETWEEN
操作符没有帮助-SQL Server无论如何调用标量函数两次。

请尝试BETWEEN操作符

WHERE functionCall(..) BETWEEN minValue AND maxValue

您可以尝试使用BETWEEN(如下所示),尽管您需要对其进行测试,因为我怀疑数据库可能会将其拆分为>=执行,这通常会显著提高性能,但需要将标量函数更改为内联表值函数

UPDATE
  a
SET
  SomeField = b.SomeField
FROM
  TableA AS a
CROSS APPLY
  dbo.oneInlineTableValuedFunction(@CurrencyFrom, e.Currency) AS ITVF
INNER JOIN
  TableB b
    ON b.Link = a.Link
WHERE
      b.CostMin <= @Cost * ITVF.exchangeRate
  AND b.CostMax >= @Cost * ITVF.exchangeRate
故意琐碎

关于此的一个示例帖子:


如果你在网上搜索
内联交叉应用标量函数性能
,我相信你会得到更多。

好主意。实际上,这可能会扩展到
=
。无论如何,SQL Server调用标量函数两次,我想这只是一种不同的表示法,所以这个建议并不能真正解决问题谢谢。似乎别无选择,只能放弃标量函数,转而使用表值函数。@10p-当应用于整个数据集时,它们的效率会大大提高。
UPDATE
  a
SET
  SomeField = b.SomeField
FROM
  TableA AS a
CROSS APPLY
  dbo.oneInlineTableValuedFunction(@CurrencyFrom, e.Currency) AS ITVF
INNER JOIN
  TableB b
    ON b.Link = a.Link
WHERE
      b.CostMin <= @Cost * ITVF.exchangeRate
  AND b.CostMax >= @Cost * ITVF.exchangeRate
CREATE FUNCTION dbo.oneInlineTableValuedFunction (
                      @currencyFrom   VARCHAR(32),
                      @currencyTo     VARCHAR(32)
)
RETURNS TABLE
AS
RETURN (
  SELECT
    exchangeRate
  FROM
    dbo.someTable
  WHERE
        currencyFrom = @currencyFrom
    AND currencyTo   = @currencyTo
)