有沒有辦法做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