PostgreSQL 强制所有数据大写

Fab*_*oni 6 postgresql postgresql-9.4 case-sensitive

有没有办法强制所有文本数据为大写,而不必重复为每个表编写函数或在客户端执行?

Erw*_*ter 17

强制正确的价值观一个东西。每列的简单CHECK约束 可以可靠地完成这项工作:

CREATE TABLE foo
   foo_id serial PRIMARY KEY
 , text_column text CHECK (upper(text_column) = text_column)
 , ...
);
Run Code Online (Sandbox Code Playgroud)

自动更正所有输入是另一回事,并不那么简单。但是可以使用通用触发器函数来完成,该函数在系统目录中查找列名和数据类型并将所有字符数据转换为大写。足够安全,但不是那么快,也不是防弹,因为更复杂的触发器可以更容易地被其他触发器规避或抵消。

一种通用的触发功能

CREATE OR REPLACE FUNCTION trg_all_upper()
  RETURNS trigger AS
$BODY$
DECLARE
   -- basic character types. possibly add citext, domains or custom types
   _typ   CONSTANT regtype[] := '{text, bpchar, varchar, \"char\"}';
   _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;
   IF _found THEN
      EXECUTE _sql USING NEW INTO NEW;
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql VOLATILE;
Run Code Online (Sandbox Code Playgroud)

每个表一个触发器

CREATE TRIGGER all_upper_bef_insupd
BEFORE INSERT OR UPDATE ON big
FOR EACH ROW EXECUTE PROCEDURE trg_all_upper();
Run Code Online (Sandbox Code Playgroud)

将具有 中定义的字符数据类型的列中的所有值 转换_typ为大写。
在 Postgres 9.4 中测试。

有关的: