Postgresql

PostgreSQL 強制所有數據大寫

  • January 16, 2022

有沒有辦法將所有文本數據強制為大寫,而無需重複為每個表編寫函式或在客戶端執行它?

強制正確的值一回事每列

的簡單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 中測試。

有關的:

引用自:https://dba.stackexchange.com/questions/102957