【问题标题】:What should return trigger BEFORE DELETE什么应该在删除之前返回触发器
【发布时间】:2017-07-11 11:54:35
【问题描述】:

我正在尝试制作简单的触发函数(Postgresql),但在所有这些情况下(只是简单的示例),我都收到相同的错误 'function did not return any row'

新:

UPDATE somewhere SET something = something - 1;
RETURN NEW;

旧:

UPDATE somewhere SET something = something - 1;
RETURN OLD;

当我在“删除之前”调用这个函数时我应该返回什么? (“插入/更新后”效果很好)

Tyvm 提示!

按要求提供完整代码: 功能:

CREATE OR REPLACE FUNCTION pictogram_frequency_on_delete()
RETURNS trigger AS
$BODY$
DECLARE

new_frequency RECORD;
target_unit RECORD;
current_row RECORD;
units_with_same_type RECORD;
what RECORD; 

BEGIN
SET search_path TO 'myScheme';

CASE TG_OP
WHEN 'DELETED' THEN what := OLD;
ELSE what:= OLD;
END CASE;

SELECT unit_type_uid INTO STRICT target_unit 
FROM unit 
WHERE unit_uid = what.unit_uid;

SELECT count(*) AS exists INTO STRICT current_row 
FROM unit_type_pictogram utp 
WHERE utp.pictogram_uid = what.pictogram_uid 
AND utp.unit_type_uid = target_unit.unit_type_uid;

IF (current_row.exists = 0) THEN
    RETURN what; /* return new/old doesnt work too */
END IF;

UPDATE unit_type_pictogram utp 
SET frequency = frequency - 1
WHERE utp.pictogram_uid = what.pictogram_uid 
AND utp.unit_type_uid = target_unit.unit_type_uid;

RETURN what; /* return new/old doesnt work too */

END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

触发器:

CREATE TRIGGER on_delete_frequency
BEFORE DELETE
ON unit_pictogram
FOR EACH ROW
  EXECUTE PROCEDURE pictogram_frequency_on_delete();

【问题讨论】:

  • 请发布完整代码
  • @JGH 发布完整代码

标签: postgresql database-trigger


【解决方案1】:

来自documentation

每个语句触发器调用的触发器函数应始终 返回 NULL。每行触发器调用的触发器函数可以返回 调用执行程序的表行(HeapTuple 类型的值),如果 他们选择。在操作之前触发的行级触发器 以下选择:

  • 它可以返回 NULL 以跳过当前行的操作。这指示执行程序不执行行级操作 调用触发器(插入、修改或删除 特定的表格行)。

  • 仅对于行级 INSERT 和 UPDATE 触发器,返回的行将成为将被插入的行或将替换正在被插入的行 更新。这允许触发器函数修改正在执行的行 插入或更新。

不打算导致任何一个的行级 BEFORE 触发器 这些行为必须小心返回同一行 传入的(即 INSERT 和 UPDATE 的 NEW 行 触发器,DELETE 触发器的 OLD 行)。


编辑

试试这样的:

CREATE OR REPLACE FUNCTION pictogram_frequency_on_delete()
RETURNS trigger AS
$BODY$
BEGIN
  UPDATE unit_type_pictogram AS utp
    SET frequency = frequency - 1
    FROM unit
    WHERE utp.pictogram_uid = OLD.pictogram_uid
      AND unit_uid = OLD.unit_uid
      AND utp.unit_type_uid = unit.unit_type_uid;
  RETURN OLD;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;

【讨论】:

  • 是的,它说“删除触发器的旧行”,但它为我返回错误
  • 向我们展示整个函数。
  • 这不是一个函数,只是一个 PL/PgSQL 块...还向我们展示CREATE TRIGGER 语句。
  • 现在也有,知道如果出错了怎么办?我删除或更新后的所有触发器都可以正常工作。
  • 你用的是什么调试器?
【解决方案2】:

你应该RETURN OLD;

您的函数必须定义为RETURNS trigger

【讨论】:

  • 我正在使用“RETURN OLD”,但调试器返回错误“'函数没有返回任何行”。 “必须定义为退货触发器”是什么意思?
猜你喜欢
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多