Postgresql
PostgreSQL 強制所有數據大寫
有沒有辦法將所有文本數據強制為大寫,而無需重複為每個表編寫函式或在客戶端執行它?
強制正確的值是一回事。每列
的簡單
CHECK
約束 可以可靠地完成這項工作:CREATE TABLE foo foo_id serial PRIMARY KEY , text_column text CHECK (upper(text_column) = text_column) , ... );
自動更正所有輸入是另一回事,並不那麼簡單。
它可以通過使用觸發器函式來完成,該觸發器函式在系統目錄中動態查找列名和數據類型並將所有字元數據轉換為大寫。足夠安全,但沒有那麼快和防彈。觸發器可以被其他觸發器規避或抵消。
一個通用的觸發功能:
CREATE OR REPLACE FUNCTION trg_all_upper() RETURNS trigger LANGUAGE plpgsql AS $func$ DECLARE -- basic character types, possibly add citext, domains or custom types _typ CONSTANT regtype[] := '{text, bpchar, varchar}'; _sql text; _found bool; BEGIN SELECT INTO _sql, _found 'SELECT ' || string_agg( CASE WHEN a.atttypid = ANY(_typ) THEN format ('upper(%1$s)::%2$s AS %1$s' , a.col, a.atttypid::regtype) ELSE col END , ', ') || ' FROM (SELECT ($1).*) t' , bool_or(a.atttypid = ANY(_typ)) FROM ( SELECT a.atttypid, quote_ident(attname) AS col FROM pg_attribute a WHERE a.attrelid = TG_RELID -- object ID of table that fired trigger AND a.attnum >= 1 -- exclude tableoid & friends AND NOT a.attisdropped -- exclude dropped columns ORDER BY a.attnum ) a; -- RAISE NOTICE '%', _sql; -- debug IF _found THEN EXECUTE _sql USING NEW INTO NEW; END IF; RETURN NEW; END $func$;
每個表一個觸發器 :
CREATE TRIGGER all_upper_bef_insupd BEFORE INSERT OR UPDATE ON big FOR EACH ROW EXECUTE PROCEDURE trg_all_upper();
在 Postgres 11 或更高版本中使用更合理的語法:
... FOR EACH ROW EXECUTE FUNCTION trg_all_upper();
將列中具有定義的字元數據類型的 所有
_typ
值轉換為大寫。在 Postgres 9.4 中測試。
有關的: