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 中测试。
有关的:
归档时间: |
|
查看次数: |
10795 次 |
最近记录: |