我有以下表格:
create table margins (
id serial primary key,
margins JSON,
created_at TIMESTAMP NOT NULL,
institution_uuid UUID NOT NULL,
created_by VARCHAR
);
字符串
和
create table margin_defaults (
id serial primary key,
model VARCHAR(255) NOT NULL,
margin FLOAT NOT NULL,
created_by VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);
型
我将以下对象数组存储在列margins
或表margins
中
insert into margins (margins, created_at, institution_uuid, created_by) VALUES ('[{"model": "samsungS23","margin": "0.5","type": "CUSTOM"},{"model": "iphone",,"margin": "0.2","type": "CUSTOM"},{"model": "pixel","margin": "0.2","type": "CUSTOM"}]', '2023-12-12 15:38:40.642428', '51d8060e-5a31-4575-b56d-c5100e94d614', 'test-runner') RETURNING *;
型
在margin_defaults
表中,我存储了不同类型边距的所有默认值。此表是一个追加/创建表,因此不会更新任何行。margins
表也是如此。但是,当向margin_defaults
表添加新条目时,我希望能够获取margins表中每个institution_uuid
的最后一组条目,并使用相同的type
更新margins
列中的相应对象与新的margin_defauts
条目的相同,但是仅当当前裕量type
被设置为DEFAULT
时。
到目前为止,我已经提出了以下触发器,但我得到了这个错误:
ERROR: function jsonb_set(jsonb, text[], double precision) does not exist
LINE 3: jsonb_set(r.margins::jsonb, ('{' || tmp_position || ',m...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: INSERT INTO margins (institution_uuid, margins, created_by) VALUES (
r.institution_uuid,
jsonb_set(r.margins::jsonb, ('{' || tmp_position || ',margin}')::text[], NEW.margin)::json,
NEW.created_by
)
CONTEXT: PL/pgSQL function update_margins_default_values_function() line 10 at SQL statement
型
我的触发器:
CREATE OR REPLACE FUNCTION update_margins_default_values_function()
RETURNS TRIGGER AS $$
DECLARE r RECORD;
DECLARE tmp_position int;
BEGIN
FOR r IN
SELECT DISTINCT ON (b.institution_uuid) * FROM (SELECT DISTINCT ON (institution_uuid) * FROM margins ORDER BY institution_uuid, created_at DESC) as b WHERE b.margins::jsonb@>'[{"type":"DEFAULT"}]' ORDER BY institution_uuid
LOOP
SELECT position FROM jsonb_array_elements(r.margins::jsonb) with ordinality arr(elem, position) INTO tmp_position WHERE elem->>'model'=NEW.model AND elem->>'type'='DEFAULT';
IF found THEN
INSERT INTO margins (institution_uuid, margins, created_by) VALUES (
r.institution_uuid,
jsonb_set(r.margins::jsonb, ('{' || tmp_position || ',margin}')::text[], NEW.margin)::json,
NEW.created_by
);
END IF;
END LOOP;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER update_margins_default_values_trigger
AFTER INSERT ON margin_defaults FOR EACH ROW EXECUTE PROCEDURE update_margins_default_values_function();
型
一个小提琴,我试图得到工作-sqlFiddle
1条答案
按热度按时间kninwzqo1#
在阅读了对我的问题有帮助的评论后,我找到了解决办法。
SELECT position FROM jsonb_array_elements(r.margins) with ordinality arr(elem, position) INTO tmp_position
返回索引从1
开始的第一个值,而不是0
,因此在插入回数组时需要从这个值中减去1
。字符串