在插入触发器以替换新数据postgres之前

时间:2018-12-30 00:22:48

标签: postgresql plpgsql database-trigger

我有一个包含两个数据列的表:col1和col2。 Col1是文本字段,而col2是时间。 Col1是必需的,col2不是必需的,因此它的默认值为null。我使用pgAdmin,这对我来说是全新的,就像sql触发器一样。我有以下触发功能代码:

CREATE OR REPLACE FUNCTION schema.table_replace()
  RETURNS trigger AS
  LANGUAGE 'plpgsql';
$BODY$
BEGIN
    (CASE
        WHEN NEW.col1='111' THEN NEW.col1='aaa'
        WHEN NEW.col1='222' THEN NEW.col1='bbb'
        WHEN NEW.col1='333' THEN NEW.col1='ccc'
        ELSE NEW.col1='error'
    END);
return NEW;
END;
$BODY$

那可能是before触发器(只是当前值应该受到影响,而不是所有行都受到影响):

CREATE TRIGGER schema.table_replace
  BEFORE INSERT
  ON schema.table
  EXECUTE PROCEDURE schema.table_replace();

说实话,我对pgAdmin一无所知,这似乎比编写代码并使用查询工具运行它要复杂得多。问题是要处理没有第二个值的情况(它是可选的),在这种情况下,应保持该行的col2不变,并且SQL代码也返回错误。 您能否提供一些帮助以使其运行并创建函数和触发器? 谢谢。

2 个答案:

答案 0 :(得分:1)

CASE作为控制结构用END CASE关闭(而表达式仅用END关闭)。在分支中有语句,它们需要用分号终止。

您的LANGUAGE也放错了位置。那属于最后。而且您不需要单引号。

IF不为空时,您可以使用col2进行替换。

CREATE OR REPLACE FUNCTION schema.table_replace()
                           RETURNS trigger AS
$BODY$
BEGIN
  IF NEW.col2 IS NOT NULL THEN
    CASE
      WHEN NEW.col1 = '111' THEN
        NEW.col1 = 'aaa';
      WHEN NEW.col1 = '222' THEN
        NEW.col1 = 'bbb';
      WHEN NEW.col1 = '333' THEN
        NEW.col1 = 'ccc';
      ELSE
        NEW.col1 = 'error';
    END CASE;
  END IF;

  RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

您还需要将触发器声明为FOR EACH ROW的{​​{1}}触发器。

触发器名称不能为架构限定。

NEW

答案 1 :(得分:0)

您的示例的主要问题是您的FOR EACH ROW语句中缺少CREATE TRIGGER子句。如果没有此子句,则创建的触发器是具有不同行为的语句触发器。您可以使用SQL功能CASE语句来解决您的任务。

CREATE OR REPLACE FUNCTION schema.table_replace()
RETURNS trigger AS
LANGUAGE 'plpgsql';
$BODY$
BEGIN
  IF NEW.col2 NOT NULL THEN
    NEW.col1 := CASE NEW.col1
                     WHEN '111' THEN 'aaa'
                     WHEN '222' THEN 'bbb'
                     WHEN '333' THEN 'ccc'
                     ELSE 'error' END CASE;
  END IF;
  RETURN NEW;
END;
$BODY$