1

在 SQL Server 中有以下更新语句:

UPDATE MY_TABLE
SET COLUMN1 = FN_GETFIRSTVALUE(T.VALUE1),
    COLUMN2 = FN_GETSECONDVALUE(T.VALUE1, T.COLUMN1)
FROM MY_TABLE AS T
INNER JOIN ...

所以FN_GETSECONDVALUE接受一个从 . 返回的输入参数FN_GETFIRSTVALUE。我考虑过使用表函数......但我看不出如何用它更新两列。还有另一种/更好的方法吗?我不想调用该函数两次,或者将其拆分为选择/更新。

4

1 回答 1

3

您的示例的最小更改如下...

UPDATE
  MY_TABLE
SET
  COLUMN1 = FN_GETFIRSTVALUE(T.VALUE1),
  COLUMN2 = FN_GETSECONDVALUE(T.VALUE1, FN_GETFIRSTVALUE(T.VALUE1))
FROM
  MY_TABLE AS T
INNER JOIN
  ...

SQL Server 擅长重用结果,因此第一个函数不一定会执行两次。但是,即使两次编写对函数的调用仍然有点混乱。

相反,您可以使用自己编写重用APPLY...

UPDATE
  MY_TABLE
SET
  COLUMN1 = first_result.val,
  COLUMN2 = second_result.val
FROM
  MY_TABLE AS T
OUTER APPLY
  (SELECT dbo.FN_GETFIRSTVALUE(T.VALUE1) AS val)          AS first_result
OUTER APPLY
  (SELECT dbo.FN_GETSEOCNDVALUE(first_result.val) AS val) AS second_result
INNER JOIN
  ...

更好的是,您可以将函数重写为表值函数。即使它只返回一个记录中的一个字段......

UPDATE
  MY_TABLE
SET
  COLUMN1 = first_result.val,
  COLUMN2 = second_result.val
FROM
  MY_TABLE AS T
OUTER APPLY
  dbo.FN_GETFIRSTVALUE(T.VALUE1)           AS first_result
OUTER APPLY
  dbo.FN_GETSEOCNDVALUE(first_result.val)  AS second_result
INNER JOIN
  ...

在这两种情况下,如果将表值函数定义为内联函数(仅单个查询),这比定义为多语句函数(包括内部变量、IF 语句等)的情况好得多。

最后,根据您的需要,您甚至可以将这两个功能包装成一个......

UPDATE
  MY_TABLE
SET
  COLUMN1 = result.val1
  COLUMN2 = result.val2
FROM
  MY_TABLE AS T
OUTER APPLY
  dbo.FN_GETBOTHVALUES(T.VALUE1)           AS result
INNER JOIN
  ...

(函数返回一条记录,其中包含 2 个字段,名为val1val2。)

所以,总而言之,你在这里有很多选择。这只是使用APPLY,还有其他选项与公用表表达式......

WITH
  step1 AS
(
  SELECT
    *,
    dbo.FUNCTION1(T.column1) AS result1
  FROM
    MY_TABLE AS T
  INNER JOIN
    ...
)
,
  step2 AS
(
  SELECT
    *,
    dbo.FUNCTION2(T.result1) AS result2
  FROM
    step1
)

UPDATE
  step2
SET
  column1 = result1,
  column2 = result2

这么多选择...

于 2012-08-16T13:14:37.660 回答