2017-01-27 26 views
0

我旁边有关系(我只保留了相关领域):为什么引用的数据在引用时仍然不可用?

CREATE TABLE "operations" (
    "id" serial NOT NULL, 
    "opdate" timestamp DEFAULT current_timestamp NOT NULL, 
); 

CREATE TABLE "prows" (
    "id" serial NOT NULL, 
    "operation_id" integer NOT NULL, 
); 

ALTER TABLE "prows" ADD CONSTRAINT "prows_fk_operation_id" FOREIGN KEY ("operation_id") 
    REFERENCES "operations" ("id") ON DELETE CASCADE ON UPDATE RESTRICT; 

CREATE TRIGGER "prow_bd_changesaldo" before delete 
    ON "prows" FOR EACH row EXECUTE PROCEDURE make_prow() 
; 

CREATE FUNCTION "make_prow"() 
RETURNS TRIGGER 
LANGUAGE plpgsql 
AS $$ 
    DECLARE _count INT; 
    BEGIN 

    SELECT count(*) /* OP.OpDate */ 
     FROM Operations OP 
     WHERE OP.ID = OLD.Operation_ID 
     INTO _count; 

    RAISE NOTICE 'COUNT: %', _count; 

    ... 

    IF TG_OP = 'DELETE' THEN RETURN OLD; ELSE RETURN NULL; END IF;/**/ 
    END;/**/ 
$$ 

我得到了count为零:当引用的行不见了

delete from operations ; 
NOTICE: COUNT: 0 
CONTEXT: PL/pgSQL function make_prow() line 1 at RAISE 
SQL statement "DELETE FROM ONLY "public"."prows" WHERE $1 OPERATOR(pg_catalog.=) "operation_id"" 
... 

因此相关的行仍然存在。这对我来说似乎非常不一致,并破坏了诚信。

有没有办法从make_prow触发得到Operations.OpDate的值?

+0

该标准[指定更严厉的排序](https://www.postgresql.org/docs/current/static/sql-createtrigger.html#SQL-CREATETRIGGER-COMPATIBILITY):* SQL指定“BEFORE DELETE在层叠的DELETE完成后级联删除触发器触发**。 PostgreSQL的行为是针对'BEFORE DELETE',在删除操作之前始终触发,甚至是级联操作。* - 但是在这两种情况下,当级联的DELETE触发时(和' BEFORE DELETE'在PostgreSQL中级联的'DELETE'触发之前触发)。 – pozs

+0

所以总之:没有这样的方式。你需要在'operations'上创建一个'BEFORE DELETE'触发器。 – pozs

+0

'CASCADE'删除仍然是一个delat,但目前的行为似乎cascade delation被实现为'AFTER DELETE'触发器。但我希望'CASCADE'的删除应该以最低优先级的'BEFORE DELETE'触发器来实现 –

回答

1

DELETE仅在operations中的行已被删除后级联到prows并不令人惊讶。

为了解决这个问题,你可以改变ON DELETE CASCADEON DELETE NO ACTIONoperations是在operations该行被删除之前删除prows依赖行定义一个BEFORE触发。这样prows上的触发器将在operations的行消失之前调用。

+0

hm((我期望听到其他解决方案,因为我有这个=)但是+1和我会接受你的,如果这将是一个答案 –

相关问题