我有两个表,documents
和events
。插入或更新文档时,我想更新事件表。
-- 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 :(得分:0)
你在函数document_to_event_birthday()
中输了一个拼写错误:在
INSERT INTO events (document, ...)
VALUES (NEW.data->'id', ...)
你应该使用
NEW.data->>'id'
现在编码函数的方式,函数尝试插入jsonb
值,该值隐式转换为text
。但是后面的值是"ham"
而不是ham
带有额外的双引号,这违反了外键约束。