当我尝试创建触发器时 PostgreSQL 中的语法错误
syntax Error in PostgreSQL when I try to create Trigger
我想在 PostgreSQL 中创建触发器。
逻辑很简单
我需要触发器,如果 published_at 已更新且 written_at 为空,请将 published_at 设置为 written_at。
我写了这个,但是失败了。有人有想法吗?
CREATE function setWrittenAt() RETURNS trigger;
AS
DECLARE old_id INTEGER;
BEGIN ;
old_id = OLD.id
IF NEW.published_at IS NOT and NEW.written_at IS null
THEN
UPDATE review SET NEW.written_at = NEW.published_at where id = old_id;
END IF ;
RETURN NEW;
END;
LANGUAGE plpgsql;
CREATE TRIGGER update_written_at
AFTER UPDATE OF published_at ON review
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
EXECUTE PROCEDURE setWrittenAt();
错误:
语法错误:7 错误:"DECLARE" 处或附近的语法错误
第 3 行:声明 old_id 整数;
您的代码中存在多个错误:
IS NOT
不是您需要的有效表达式 IS NOT NULL
。
- 在
BEGIN
和 returns
子句之后不能有 ;
- 你忘了把函数体用字符串括起来(如果你用 dollar quoting
会更容易写
- 你也不需要不必要的(额外的)
UPDATE
如果你把它变成 before
触发器
CREATE function setwrittenat()
RETURNS trigger
AS
$$
BEGIN
IF NEW.published_at IS NOT NULL and NEW.written_at IS null THEN
NEW.written_at := = NEW.published_at; --<< simply assign the value
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
然后使用BEFORE
触发器:
CREATE TRIGGER update_written_at
<b>BEFORE</b> UPDATE OF published_at ON review
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
FOR EACH ROW
EXECUTE PROCEDURE setWrittenAt();
这是基于 a_horse_with_no_name
s ,因为它会抛出错误。
ERROR: statement trigger's WHEN condition cannot reference column values
您需要添加FOR EACH ROW
,否则条件触发器将不起作用。
If neither is specified, FOR EACH STATEMENT is the default.
Statement-level triggers can also have WHEN conditions, although the feature is not so useful for them since the condition cannot refer to any values in the table.
CREATE TRIGGER update_written_at
BEFORE UPDATE OF published_at ON review
FOR EACH ROW
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
EXECUTE PROCEDURE setWrittenAt();
我还不能发表评论,这就是我将此作为答案发布的原因。
我想在 PostgreSQL 中创建触发器。
逻辑很简单
我需要触发器,如果 published_at 已更新且 written_at 为空,请将 published_at 设置为 written_at。
我写了这个,但是失败了。有人有想法吗?
CREATE function setWrittenAt() RETURNS trigger;
AS
DECLARE old_id INTEGER;
BEGIN ;
old_id = OLD.id
IF NEW.published_at IS NOT and NEW.written_at IS null
THEN
UPDATE review SET NEW.written_at = NEW.published_at where id = old_id;
END IF ;
RETURN NEW;
END;
LANGUAGE plpgsql;
CREATE TRIGGER update_written_at
AFTER UPDATE OF published_at ON review
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
EXECUTE PROCEDURE setWrittenAt();
错误:
语法错误:7 错误:"DECLARE" 处或附近的语法错误 第 3 行:声明 old_id 整数;
您的代码中存在多个错误:
IS NOT
不是您需要的有效表达式IS NOT NULL
。- 在
BEGIN
和returns
子句之后不能有;
- 你忘了把函数体用字符串括起来(如果你用 dollar quoting 会更容易写
- 你也不需要不必要的(额外的)
UPDATE
如果你把它变成before
触发器
CREATE function setwrittenat()
RETURNS trigger
AS
$$
BEGIN
IF NEW.published_at IS NOT NULL and NEW.written_at IS null THEN
NEW.written_at := = NEW.published_at; --<< simply assign the value
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
然后使用BEFORE
触发器:
CREATE TRIGGER update_written_at
<b>BEFORE</b> UPDATE OF published_at ON review
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
FOR EACH ROW
EXECUTE PROCEDURE setWrittenAt();
这是基于 a_horse_with_no_name
s
ERROR: statement trigger's WHEN condition cannot reference column values
您需要添加FOR EACH ROW
,否则条件触发器将不起作用。
If neither is specified, FOR EACH STATEMENT is the default.
Statement-level triggers can also have WHEN conditions, although the feature is not so useful for them since the condition cannot refer to any values in the table.
CREATE TRIGGER update_written_at
BEFORE UPDATE OF published_at ON review
FOR EACH ROW
WHEN (OLD.published_at IS DISTINCT FROM NEW.published_at)
EXECUTE PROCEDURE setWrittenAt();
我还不能发表评论,这就是我将此作为答案发布的原因。