2017-10-15 21 views
1

私は2つのテーブルdocumentseventsを持っています。ドキュメントが挿入または更新されると、イベントテーブルが更新されます。AFTER INSERT OR UPDATEトリガのPostgreSQLからの外部キー制約違反の取得

-- Create the document store table 
CREATE TABLE documents (
    id TEXT PRIMARY KEY, 
    parent TEXT REFERENCES documents, 
    data JSONB, 
    created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), 
    updated TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now() 
); 

-- Create the normalized event table 
CREATE TABLE events (
    document TEXT REFERENCES documents, 
    type TEXT NOT NULL, 
    eventDate date NOT NULL, 
    title TEXT, 
    subtitle TEXT, 
    description TEXT, 
    PRIMARY KEY(document, type, eventDate) 
); 

私はヘルパー関数やトリガを持っている:

-- Keep the update documentDB column valid 
CREATE OR REPLACE FUNCTION update_modified_column() 
RETURNS TRIGGER AS $$ 
BEGIN 
    NEW.updated = now(); 
    RETURN NEW; 
END; 
$$ language 'plpgsql'; 

CREATE TRIGGER trigger_patents_updated BEFORE UPDATE ON documents 
    FOR EACH ROW EXECUTE PROCEDURE update_modified_column(); 

-- Put a document 
CREATE OR REPLACE FUNCTION PutDocument(in_data JSON) 
RETURNS TEXT AS $$ 
DECLARE 
    r_id TEXT; 
BEGIN 
    INSERT INTO documents (id, parent, data) VALUES (in_data::JSONB->>'id', 
     in_data::JSONB->>'parent', in_data::JSONB) 
    ON CONFLICT (id) DO UPDATE SET data=in_data::JSONB RETURNING id 
     INTO r_id; 
    RETURN r_id; 
END; 
$$ language 'plpgsql'; 

その後、私は私が文書のそれのエラーを挿入しようとすると、イベントテーブルに

-- Create birthday events 
CREATE OR REPLACE FUNCTION document_to_event_birthday() 
RETURNS TRIGGER AS $$ 
BEGIN 
    INSERT INTO events (document, type, eventDate, title, subtitle, description) 
    VALUES(NEW.data->'id', 'BIRTH', to_date(NEW.data->'birth'->>'date', 'YYYY-MM-DD'), 'title', 'subtitle', 'description') 
    ON CONFLICT ON CONSTRAINT events_pkey DO NOTHING; 
    RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

CREATE TRIGGER document_to_event_birthday 
    AFTER INSERT OR UPDATE ON documents 
    FOR EACH ROW EXECUTE PROCEDURE document_to_event_birthday(); 

を更新する必要がありますトリガを持っていますdocument_to_event_birthday機能です。

PutDocument('{"id": "ham", "test": "value", "birth": { "date": "2011-06-02" }}'); 

は私に、私はエラーが発生した後の表を見れば、彼らは両方とも空です

ERROR: insert or update on table "events" violates foreign key constraint "events_document_fkey" 
DETAIL: Key (document)=("ham") is not present in table "documents". 
CONTEXT: SQL statement "INSERT INTO events (document, type, eventDate, title, subtitle, description) 
    VALUES(NEW.data->'id', 'BIRTH', to_date(NEW.data->'birth'->>'date', 'YYYY-MM-DD'), 'title', 'subtitle', 'description') 
    ON CONFLICT ON CONSTRAINT events_pkey DO NOTHING" 
PL/pgSQL function document_to_event_birthday() line 3 at SQL statement 
SQL statement "INSERT INTO documents (id, parent, data) VALUES (in_data::JSONB->>'id', 
     in_data::JSONB->>'parent', in_data::JSONB) 
    ON CONFLICT (id) DO UPDATE SET data=in_data::JSONB RETURNING id" 
PL/pgSQL function putdocument(json) line 5 at SQL statement 

を与えます。だから私のトリガは、挿入/ドキュメントテーブルの更新後に起こっていません。

これを修正するにはどうすればよいですか?

答えて

0

あなたが機能document_to_event_birthday()にタイプミスをした:

INSERT INTO events (document, ...) 
    VALUES (NEW.data->'id', ...) 

では、関数は、現在コーディングされている

NEW.data->>'id' 

方法を使用している必要があり、関数がjsonb値を挿入しようとすると、その暗黙的にtextに変換されます。しかし、値はhamではなく、二重引用符が余分にある"ham"であり、これは外部キー制約に違反します。