【问题标题】:Sanitize input to a column in postgres清理 postgres 中列的输入
【发布时间】:2012-09-29 05:23:18
【问题描述】:

所以,我认为这应该相当简单,但文档使它看起来有点复杂。我在 PostgreSQL(目前是 8.1)中编写了一个 SQL 函数,它对一些字符串输入进行了一些清理。值得一提的是,该字符串是一个 LDAP 专有名称,我希望逗号后始终没有空格 - 函数是 clean_dn(),它返回清理后的 DN。我想做同样的事情来强制对另外几列的所有输入为小写,等等——一旦我弄清楚这部分,这应该很容易。

无论如何,只要有人尝试插入或更新和修改该列,我希望此函数在表的“dn”列上运行。但是我能找到的所有规则示例似乎都假设所有插入/更新查询都会一直修改表中的所有列。在我的情况下,情况并非如此。我认为我真正想要的是一个仅更改值而不是返回 true 或 false 的约束,但这对于约束的 SQL 概念似乎没有意义。我是否让我的规则对新表执行更新?我是否必须为每个可能的新值组合创建一个新规则?如果我添加一个列,我是否必须检查并更新我的所有规则组合以反映每个可能的新列组合?

必须有一个简单的方法......

【问题讨论】:

  • 是的,我知道我可以在客户端进行验证。如果数据库只能定义一次规则,那么在我触及这个值的每个地方重复代码是愚蠢的.. :)
  • 你也许可以做一些像ALTER TABLE table_name ADD CONSTRAINT constraint_name CHECK (clean_dn(dn) = dn)这样简单的事情

标签: postgresql validation plpgsql sanitization postgresql-8.1


【解决方案1】:

首先,更新到当前版本的 PostgreSQL。 8.1 早就死了,被遗忘了,没有得到支持,而且非常非常老了.. 你明白我的意思吗? Current version is PostgreSQL 9.2.

然后,使用触发器代替规则。它更简单。这是大多数人的方式。我愿意。

对于表 tbl 中的列 col ...

首先,创建一个trigger function

CREATE OR REPLACE FUNCTION trg_tbl_insupbef()
  RETURNS trigger AS
$BODY$
BEGIN

NEW.col := f_myfunc(NEW.col);  -- your function here, must return matching type

RETURN NEW;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

然后在trigger 中使用它。
对于古代 Postgres 8.1:

CREATE TRIGGER insupbef
  BEFORE INSERT OR UPDATE
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_insupbef();

适用于现代 Postgres (9.0+)

CREATE TRIGGER insbef
  BEFORE INSERT OR UPDATE OF col  -- only call trigger, if column was updated
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_tbl_insupbef();

您可以将更多内容打包到一个触发器中,但是您不能仅针对一列设置 UPDATE 触发器...

【讨论】:

  • 我很想升级 dbms,但是这台服务器上的支持一团糟,这意味着它必须运行 RHEL 5。我背负着旧的 postgres、旧的 python、旧的perl 等。如果是我来管理...无论如何,触发器看起来确实不错。并且可能会给所有者带来更多压力以迁移到受支持的版本...
猜你喜欢
  • 2021-06-17
  • 2012-12-22
  • 2020-11-04
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2018-02-18
  • 2012-10-15
  • 2011-07-27
相关资源
最近更新 更多