2017-10-15 15 views
1

我有两个表,documentsevents。当插入或更新文档时,我想更新事件表。在AFTER INSERT或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,并带有双引号,这违反了外键约束。