在插入触发器之前替换新数据postgres
Before insert trigger to replace new data postgres
我有一个包含两个数据列的 table: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$
这可能是之前的触发器(应该只影响当前值,而不是所有行):
CREATE TRIGGER schema.table_replace
BEFORE INSERT
ON schema.table
EXECUTE PROCEDURE schema.table_replace();
说实话,我对pgAdmin一窍不通,感觉比写代码再用查询工具运行复杂多了。问题是处理没有第二个值(它是可选的)的情况,在这种情况下,行的 col2 应该保持不变,SQL 代码 returns 错误也是如此。
您能否提供一些帮助使其 运行 并创建函数和触发器?
谢谢
CASE
作为控制结构以 END CASE
结束(而表达式仅以 END
结束)。并且在分支中有语句,它们需要以分号结束。
你的LANGUAGE
也放错地方了。那属于最后。而且你不需要单引号。
当 col2
不为空时,您可以使用 IF
仅进行替换。
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
触发器才能使 NEW
工作。
并且触发器名称不能是模式限定的。
CREATE TRIGGER table_replace
BEFORE INSERT
ON schema.table
FOR EACH ROW
EXECUTE PROCEDURE schema.table_replace();
您的示例的主要问题是您的 CREATE TRIGGER
语句中缺少 FOR EACH ROW
子句。如果没有这个子句,创建的触发器是一个具有不同行为的语句触发器。您的任务可以通过 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$
我有一个包含两个数据列的 table: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$
这可能是之前的触发器(应该只影响当前值,而不是所有行):
CREATE TRIGGER schema.table_replace
BEFORE INSERT
ON schema.table
EXECUTE PROCEDURE schema.table_replace();
说实话,我对pgAdmin一窍不通,感觉比写代码再用查询工具运行复杂多了。问题是处理没有第二个值(它是可选的)的情况,在这种情况下,行的 col2 应该保持不变,SQL 代码 returns 错误也是如此。 您能否提供一些帮助使其 运行 并创建函数和触发器? 谢谢
CASE
作为控制结构以 END CASE
结束(而表达式仅以 END
结束)。并且在分支中有语句,它们需要以分号结束。
你的LANGUAGE
也放错地方了。那属于最后。而且你不需要单引号。
当 col2
不为空时,您可以使用 IF
仅进行替换。
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
触发器才能使 NEW
工作。
并且触发器名称不能是模式限定的。
CREATE TRIGGER table_replace
BEFORE INSERT
ON schema.table
FOR EACH ROW
EXECUTE PROCEDURE schema.table_replace();
您的示例的主要问题是您的 CREATE TRIGGER
语句中缺少 FOR EACH ROW
子句。如果没有这个子句,创建的触发器是一个具有不同行为的语句触发器。您的任务可以通过 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$