有没有办法做INSERT INTO t1 SELECT * FROM...
,使它失败如果列名不重合?列安全的INSERT INTO t1 SELECT * FROM ...`
我在使用Postgresql 9.x列名不提前知道。
动机:我在做由(相当标准)的物化视图的周期性刷新PL/pgSQL的过程:
CREATE OR REPLACE FUNCTION matview_refresh(name) RETURNS void AS
$BODY$
DECLARE
matview ALIAS FOR $1;
entry matviews%ROWTYPE;
BEGIN
SELECT * INTO entry FROM matviews WHERE mv_name = matview;
IF NOT FOUND THEN
RAISE EXCEPTION 'Materialized view % does not exist.', matview;
END IF;
EXECUTE 'TRUNCATE TABLE ' || matview;
EXECUTE 'INSERT INTO ' || matview || ' SELECT * FROM ' || entry.v_name;
UPDATE matviews SET last_refresh=CURRENT_TIMESTAMP WHERE mv_name=matview;
RETURN;
END
我宁愿一个TRUNCATE
后跟一个SELECT * INTO
而不是DROP/CREATE因为它看起来更加轻便和并发友好。如果有人从视图中添加/删除列(然后我会执行DROP/CREATE),那么它会失败,但这并不重要,在这种情况下刷新不会完成,我们很快就会发现问题。重要的是今天发生的事情:有人改变了视图(相同类型)的两列的顺序,刷新插入了伪造数据。
您是否无法使用postgresql指定列列表? ('INSERT INTO t1(col1,col2,...)SELECT *') – Kermit
我想他希望它可以用于任何表,只要它们具有相同的列。 – ThiefMaster
@njk:列名不提前知道 – leonbloy