我正在寻找一个新列添加到一个预先存在的表中,该表中充满了值。新列将是
NOT NULL
,因此对于每个预先存在的行,它都需要一个值。
我正在寻找此列的初始值,该初始值是根据创建列时表中的其他值计算的,而仅在创建列时计算。
我有一个非常具体的用例,所以我不是在寻找解决方法。我将举一个非常简单的例子来说明我正在寻找的东西:
说我有这个数据:
CREATE TABLE numbers (
value1 INTEGER NOT NULL,
value2 INTEGER NOT NULL
);
INSERT INTO numbers(value1, value2) VALUES (10, 20), (2, 5);
我希望在
value3
表上创建一个新列 numbers
,在创建时,它始终等于其相应的 value1
和 value2
列的总和。
例如:
ALTER TABLE numbers ADD COLUMN value3 INTEGER;
/* ... some more logic which calculates the initial values ... */
ALTER TABLE numbers
ALTER COLUMN value3 SET NOT NULL;
完成后,我想要以下数据:
-- The 3rd value will be the sum of the first 2 values
SELECT * FROM numbers;
value1 | value2 | value3
-------+--------+-------
10 | 20 | 30
2 | 5 | 7
我稍后需要更新数据,也许会破坏关系
value3 === (value1 + value2)
:
UPDATE numbers SET value3=9823 WHERE value1=10;
如何实现将计算的初始值插入
value3
列的步骤?
我发现了一个简单的方法!以下添加具有所需初始值的
value3
列:
ALTER TABLE numbers
ADD COLUMN value3 INTEGER; -- Exclude the NOT NULL constraint here
UPDATE numbers SET value3=value1+value2; -- Insert data with a regular UPDATE
ALTER TABLE numbers
ALTER COLUMN value3 SET NOT NULL; -- Now set the NOT NULL constraint
当 postgres 具有用于要应用于新列的计算的本机函数时,此方法很好。例如。在这种情况下,我想要的计算是“总和”,而 postgres 通过
+
运算符进行计算。对于 postgres 本身不提供的操作,此方法将更加复杂。
您有两种选择:
如果您需要将计算值存储在触发器中的数据库中。
CREATE OR REPLACE FUNCTION sum_columns()
RETURNS trigger AS
$BODY$
BEGIN
NEW.value := new.value1+new.value2;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER calculated_colum AFTER INSERT OR UPDATE ON numbers
FOR EACH ROW EXECUTE PROCEDURE sum_columns();
如果您不需要将计算值存储在数据库中,您可以使用函数索引
CREATE INDEX sum_columns_idx ON numbers ((value1+value2));