INSERT INTO t1 SELECT * FROM...
列名が一致しない場合に失敗するような方法はありますか?
Postgresql9.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
私は、DROP / CREATETRUNCATE
の代わりに、より軽量で同時実行に適しているように見えたので、その後に続くことを好みました。SELECT * INTO
誰かがビューから列を追加/削除すると失敗しますが(その後、DROP / CREATEを実行します)、問題ではありません。その場合、更新は完了せず、すぐに問題を検出します。重要なのは、今日起こったことです。誰かが(同じタイプの)ビューの2つの列の順序を変更し、更新によって偽のデータが挿入されました。