【问题标题】:T-SQL Update table columns using functionT-SQL 使用函数更新表列
【发布时间】:2026-01-11 08:00:02
【问题描述】:

我有下表:

RecordID 
Name
Col1
Col2
....
ColN

RecordIDBIGINT PRIMARY KEY CLUSTERED IDENTITY(1,1)RecordIDName 已初始化。其他列是 NULL。

我有一个函数通过Name返回有关其他列的信息。

为了初始化我的表,我使用以下算法:

  1. 创建循环
  2. 获取一行,选择其Name
  3. 使用所选名称执行函数,并存储其结果 在临时变量中
  4. 在表中插入临时变量
  5. 移至下一条记录

有没有办法在不循环的情况下做到这一点?

【问题讨论】:

    标签: tsql function loops updates


    【解决方案1】:

    Cross apply 基本上就是为此而建的

    SELECT D.deptid, D.deptname, D.deptmgrid
        ,ST.empid, ST.empname, ST.mgrid
    FROM Departments AS D
        CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST;
    

    Using APPLY

    UPDATE some_table
    SET some_row = another_row,
        some_row2 = another_row/2
    FROM some_table st
      CROSS APPLY
        (SELECT TOP 1 another_row FROM another_table at WHERE at.shared_id=st.shared_id)
    WHERE ...
    

    using cross apply in an update statement

    【讨论】:

      【解决方案2】:

      如果表中已有记录,则可以简单地说如下。

      UPDATE MyTable
      SET 
          col1 = dbo.col1Method(Name),
          col2 = dbo.col2Method(Name),
          ...
      

      在插入新记录时,假设 RecordID 是自动生成的,你可以说

      INSERT INTO MyTable(Name, Col1, Col2, ...)
      VALUES(@Name, dbo.col1Method(@Name), dbo.col2Method(@name), ...)
      

      其中@Name 包含名称列的值。

      【讨论】:

      • 我只有一个功能。如果我这样使用in,是缓存结果,还是只针对一行执行多次?
      • 如果您只有一个方法可以被调用来填充一列,那么该函数将被调用与数据库中存在的行数一样多。如果你想限制这应该运行的行集,你显然可以指定一个 WHERE 子句来限定这些行集。
      • 是的,我知道这一点。我想为每一行执行函数。我的观点是,这些函数返回 10 列,而不是一列。
      • 我没有得到一个函数调用返回给定行的所有列。无论如何,我看到你从另一个答案中得到了你想要的。
      • 这是最简单的答案。使用函数的输出更新列是一种非常基本、非常有用的方法。