【问题标题】:Populate extra database column depending on other column values根据其他列值填充额外的数据库列
【发布时间】:2015-03-02 17:16:03
【问题描述】:

我有一个从应用程序收集数据的数据库。现在,我必须创建另一列,该列将根据其他列中的值填充预定义数据。所以,没有数学,只是查找另外两列中的值并将数据插入到新添加的列中。

例子

id     column1     column2    newColumn
1      15          3          100

所以当 column1 有 15,column2 有 3 时,newColumn 应该自动填充 100。同样,数字 100 是预先定义的,而不是计算出来的。

我知道我可以对新条目使用触发器,但是数据库已经输入了大量数据,那么有没有办法为已经存在的数据自动填充 newColumn?

编辑--------------------------------

所以我可以使用更新来填充已输入记录的列?!

我可以创建一个触发器,它会等待这两个值,直到两个值都输入它才会返回 NULL?

【问题讨论】:

  • 一般来说,存储计算的列值并不是一个好主意。经常会发现旧的、不一致的值。如果真的需要,触发器很棒。但在大多数情况下,视图是“自动填充”的最佳解决方案!
  • 100 是 predifned--意思是什么意思它是一个随机数生成器或者应该是唯一的请详细说明
  • @koushikveldanda 我预先知道当 column1 为 15 且 column2 为 3 时,newColumn 必须为 100..

标签: sql sql-server database auto-populate


【解决方案1】:

您可以创建标量函数:

ALTER FUNCTION [dbo].[Test] ( @column1 INT, @column2 INT)
RETURNS INT
    WITH SCHEMABINDING
AS
    BEGIN

        DECLARE @r INT

        IF @column1 = 15 AND @column2 = 3
            SET @r = 100
        ELSE
            SET @r = NULL

        RETURN @r
    END

然后添加新的计算列:

ALTER TABLE TableName ADD ColumnName AS dbo.Test(column1, column2) PERSISTED

持久化意味着,该列不是即时计算的,而是保存数据。 这就是您使用WITH SCHEMABINDING 的原因。如果没有绑定,您将无法使该列持久化。

您还可以使用@Rhys Jones 回答中的简单更新语句更新当前数据,并在表上添加触发器,例如:

ALTER TRIGGER trTest ON TableName
AFTER INSERT, UPDATE
AS
BEGIN
    IF UPDATE(column1) AND UPDATE(column2)
        BEGIN
            UPDATE  TableName
            SET     NewColumn = CASE
                                  WHEN column1 = 15 and column2 = 3 then 100
                                  ELSE NULL
                                END
            FROM    Inserted i
                    JOIN TableName t ON t.id = i.id
        END
END 

【讨论】:

  • 请注意,持久化计算列(甚至在其上具有索引)并不能保证服务器不会选择重新计算查询中列的值。如果此类列使用 UDF,优化器会很高兴地调用 UDF。 A Computed Column Defined with a UDF Might Impact Query Performancedba.stackexchange.com/questions/18716/…
  • @giorgi 一个问题?如果 column1 和 column2 没有同时更新怎么办。我希望当这两个字段都有值时触发触发器。你写的这个 UPDATE 会起作用吗?
  • @gogo_rulez, IF UPDATE(column1) AND UPDATE(column2) 这将在两者都更新时触发。 IF UPDATE(column1) OR UPDATE(column2),如果两个或两者中的任何一个被更新,就会触发。
【解决方案2】:

您可以只使用一个 UPDATE 来更新缺失值,然后使用 TRIGGER 来获取新行。

    update MyTable set
        newColumn = case 
                        when column1 = 15 and column2 = 3 then 100
                        when ...
                    end

    where
        newColumn is null

但是,请注意上面@jarlh 所说的,通常有更好的方法来执行此操作,例如视图或计算列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2020-11-14
    • 1970-01-01
    相关资源
    最近更新 更多