2017-03-29 1 views
0

정규화 규칙을 준수하려고하는 엔티티 관계 모델이 있습니다. 그러나 현재 PostGIS를 통해 QGIS를 작업하고 관련 데이터 만 보유하기 위해 몇 가지보기를 수행하고 이러한보기를 QGIS에 표시하고보기에서 수정 한 내용에 따라 해당 표를 업데이트하려고합니다.PostgreSQL/PostGIS보기에서 테이블 데이터 업데이트

예를 들어 케이블이 내가 작업해야하는 데이터를 포함하는 세 개의 테이블을 가지고 있고, modele_cable은 뷰를 채울 정보를 담고있는 참조 테이블 (약한 엔티티)과, modele_table의 약한 엔티티 인 type_cable 보기에 관련된 일부 정보가 들어 있습니다. 예를 들면 :

CREATE TABLE test.cable(
     id_cable serial NOT NULL, 
     id_modele_cable integer, 
     geom geometry(MultiLineString,2154), 
     CONSTRAINT prk_constraint_cable PRIMARY KEY (id_cable), 
     CONSTRAINT fk_cable_id_modele_cable FOREIGN KEY (id_modele_cable) 
      REFERENCES test.modele_cable (id_modele_cable) 
    ); 
    CREATE TABLE test.modele_cable(
     id_modele_cable serial NOT NULL, 
     id_type_cable integer, 
     CONSTRAINT prk_constraint_modele_cable PRIMARY KEY (id_modele_cable), 
     CONSTRAINT fk_modele_cable_id_type_cable FOREIGN KEY (id_type_cable) 
      REFERENCES test.type_cable (id_type_cable) 
    ); 
    CREATE TABLE test.type_cable(
     id_type_cable serial NOT NULL, 
     nb_fo integer, 
     CONSTRAINT prk_constraint_type_cable PRIMARY KEY (id_type_cable) 
    ); 
    CREATE VIEW public.cable_ok AS 
    SELECT cable.id_cable, 
     cable.designation, 
     type_cable.nb_fo, 
     cable.geom 
     FROM test.cable 
     LEFT JOIN test.modele_cable ON cable.id_modele_cable=modele_cable.id_modele_cable 
     LEFT JOIN test.type_cable ON type_cable.id_type_cable=modele_cable.id_type_cable; 

내가하고 싶은 일을하는 방법에 대한 정보를 찾을하지 않으며도 가능하고, 그렇지 않은 경우 어떻게 해결 될 수 있습니다. 나는 PostGIS의 뷰에서 수정을 감지하고 이에 따라 '케이블'테이블을 업데이트하는 트리거를 만들려고했지만 그렇게 할 수 없었습니다 (이전에 다른 컨텍스트에서 트리거를 만들었을뿐입니다. 고통스럽게). 나는 뷰의 테이블 내부에서 수동으로 뷰를 업데이트하는 것이 불가능하다는 것도 알아 차렸다.

누군가이 단서를 해결할 수있는 실마리, 방향, 도움, 경험이 있습니까?

UPDATE 여기 내가 그것을 구현하는 시도로 트리거입니다 :

create or replace function tout.update_cable_view() returns trigger as 
    $body$ 
    begin 
    select modele_cable.id_modele_cable 
    into cable.id_modele_cable 
    from test.cable 
    inner join test.modele_cable on cable.id_modele_cable=modele_cable.id_modele_cable 
    inner join test.type_cable on modele_cable.id_type_cable=type_cable.id_type_cable, 
    public.cable_ok 
    where cable_ok.nb_fo=type_cable.nb_fo; 
    return null; 
    end; 
    $body$ 
    language plpgsql; 

    create trigger t_update_cable_view 
    instead of insert or update on public.cable_ok 
    for each row 
    execute procedure tout.update_cable_view(); 

UPDATE 여기에 2 작동해야 트리거 기능은,하지만되지 않습니다 :

create or replace function tout.update_cable_view() returns trigger as 
$body$ 
begin 
update test.cable 
set id_modele_cable = (select id_modele_cable from test.modele_cable 
inner join test.type_cable on 

modele_cable.id_type_cable=type_cable.id_type_cable 
    where new.nb_fo=type_cable.nb_fo and old.id_cable=new.id_cable); 
return new; 
end; 
$body$ 
language plpgsql; 
+1

나는 당신이 원하는 것을 잘 모릅니다. [업데이트 가능한보기] (https://www.postgresql.org/docs/current/static/rules-views.html#RULES-VIEWS-UPDATE)? 그렇다면, 당신은 그것에 대한'INSTEAD OF' 트리거를 작성하려했지만 실패 했습니까? 컨텍스트를 추가하고 실패한 시도를 추가하십시오. – pozs

+0

QGIS에서 뷰 레이어의 일부 정보를 업데이트하거나 QGIS의 뷰에서 새 튜플을 만들거나 삭제할 때 '케이블'테이블이 적절히 업데이트되기를 바랍니다. 구현하려고 시도한 트리거 시도가 실패하여 원래 게시물을 편집했습니다. 큰 문제는 트리거 함수에 '새로운'변수가 없다는 것입니다 ... –

+0

'NEW' "row"는'INSTEAD OF' 트리거에도 정의되어 있습니다. 또한'RETURN NEW' ([NULL' 대신에 [NULL'] (https://www.postgresql.org/docs/current/static/plpgsql-trigger.html))를 원할 수도 있습니다 - *'INSTEAD OF' 트리거는 그들이 업데이트를 수행하지 않았 음을 알리기 위해 null을 반환하고이 행에 대한 나머지 작업은 건너 뜁니다. *) - 실제로 삽입/업데이트되는 뷰에서 ** SELECT **를하지 말아야합니다. . – pozs

답변

0

나는 규칙을 사용하여 원하는 것을하는 또 다른 방법을 찾았습니다. 내 생각 엔 PostgreSQL은 뷰 저장을 허용하지 않는다. INSTEAD 규칙을 사용하면보기를 저장하지 않고 원본 테이블을 업데이트하여 자동으로보기를 업데이트합니다. 다음은 업데이트를위한 코드입니다.

create rule "_test_rule" as 
on update to public.cable_ok 
do instead update test.cable 
set id_modele_cable = (select id_modele_cable from test.modele_cable 
inner join test.type_cable on modele_cable.id_type_cable=type_cable.id_type_cable 
where new.nb_fo=type_cable.nb_fo and new.id_cable=cable.id_cable) 
where old.id_cable=cable.id_cable; 
관련 문제