sql - TRIGGER BEFORE DELETE,不删除表中的数据

标签 sql postgresql

当一行被修改/删除时,我正在处理我的数据库的历史记录。 我的主表是“bati”和历史表“bati_history”,当删除或修改一行时,触发器假设将所有旧数据插入到 bati_history 中,然后在主表(bati)中删除。但是使用我的代码,该行被插入到历史记录中但没有在主表中删除,我不知道为什么。

我使用的是 PostgreSQL 11.2 64 位

代码:

主表:

CREATE TABLE IF NOT EXISTS bati(
    id_bati BIGSERIAL NOT NULL UNIQUE,
    code_bati VARCHAR(25) NOT NULL,
    code_parcelle CHAR(50) NOT NULL,
    ...);

历史表:

CREATE TABLE IF NOT EXISTS bati_history(
    id_history BIGSERIAL NOT NULL PRIMARY KEY,
    event CHAR(10) NOT NULL,
    date_save_history TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
    id_bati BIGINT NOT NULL,
    code_bati VARCHAR(25) NOT NULL,
    code_parcelle CHAR(50) NOT NULL,
        ...);

函数

CREATE FUNCTION archive_bati() RETURNS TRIGGER AS $BODY$
  BEGIN
    IF (TG_OP = 'DELETE') THEN
      INSERT INTO bati_history (event,id_bati,code_bati,code_parcelle,...)
      VALUES ('DELETE',OLD.id_bati,OLD.code_bati,OLD.code_parcelle,OLD....);
    ELSIF (TG_OP = 'UPDATE') THEN
      INSERT INTO bati_history (event,id_bati,code_bati,code_parcelle,...)
      VALUES ('UPDATE',OLD.id_bati,OLD.code_bati,OLD.code_parcelle,OLD....);
    END IF;
    RETURN NEW;
  END;
$BODY$
LANGUAGE 'plpgsql';

触发器:

CREATE TRIGGER bati_trigger_before_delete BEFORE DELETE
ON bati FOR EACH ROW
EXECUTE PROCEDURE archive_bati();

CREATE TRIGGER bati_trigger_before_update BEFORE UPDATE
ON bati FOR EACH ROW
EXECUTE PROCEDURE archive_bati();

当我尝试 DELETE FROM bati; 时,我希望复制 bati_history 中的每一行,然后从 bati 中删除它们,但它们并没有从 bati 中删除,而且我的输出没有错误:

test=# INSERT INTO bati (id_bati,code_bati,code_parcelle,id_interne) VALUES (5,'CODEBATI001','CODEPARC001',02);
INSERT 0 1
test=# INSERT INTO bati (id_bati,code_bati,code_parcelle,id_interne) VALUES (6,'CODEBATI002','CODEPARC002',02);
INSERT 0 1
test=#  DELETE FROM bati;
DELETE 0

(对不起我的英语我是法国人)

最佳答案

您应该使用 if-else 分支来返回 NEWOLD,具体取决于触发器操作。变量 TG_OP 具有文本类型,可以直接在插入查询中使用。

所以,函数定义变成:

CREATE FUNCTION archive_bati() 
    RETURNS TRIGGER AS $$
BEGIN
INSERT INTO bati_history (event,id_bati,code_bati,code_parcelle) 
VALUES (TG_OP, OLD.id_bati, OLD.code_bati, OLD.code_parcelle);
IF TG_OP = 'DELETE' 
    THEN RETURN OLD; 
    ELSE RETURN NEW;
END IF;
END;
$$ LANGUAGE PLPGSQL;

此外,当 1 个触发器就足够时,我似乎没有必要定义两个触发器:

CREATE TRIGGER bati_trigger_before_update BEFORE UPDATE OR DELETE
ON bati FOR EACH ROW
EXECUTE PROCEDURE archive_bati();

关于sql - TRIGGER BEFORE DELETE,不删除表中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56544430/

相关文章:

Mysql 从多值字段中获取唯一值

mysql - 从 MySql 表中选择并删除 x 行

mysql - 我的 MySQL 查询不会返回任何结果?

json - 使用 Postgres 的 JSON 图的邻接列表

ruby-on-rails - 无法使用 Rails 创建脚手架 - 无密码错误

postgresql - Postgres ODBC 驱动模块

.net - 客户端服务器安装包.NET

sql - 在SQL中,如何使用LIKE匹配最多(但不超过)个通配符?

python - 在 Django 应用程序中,即使迁移文件夹文件被删除,此错误也存在 'relation "blog_no_of_views“不存在”

postgresql - 我应该将 ASCII-only varchar 保存为 UTF-8 还是 ASCII?