现在我使用手动将json解析为插入字符串,如此
insert into Table (field1, field2) values (val1, val2)
但是从json插入数据的方式并不舒服! 我找到了函数json_populate_record并尝试使用它:
create table test (id serial, name varchar(50));
insert into test select * from json_populate_record(NULL::test, '{"name": "John"}');
但它失败并显示消息:列“id”中的空值违反了非空约束 PG知道id是连续的,但假装是个傻瓜。与默认情况下的所有玩家一样。
将数据从json插入表中是否有更优雅的vay?
答案 0 :(得分:13)
json_populate_record
没有简单的方法可以返回一个标记,表示“生成此值”。
PostgreSQL not 允许您插入NULL
以指定应生成值。如果您要求NULL
Pg期望意味着 NULL
,并且不想再猜测你。另外,生成的列没有NOT NULL
约束是完全可以的,在这种情况下,将NULL
插入其中是完全正确的。
如果你想让PostgreSQL使用表默认值,有两种方法可以做到这一点:
INSERT
列列表中的该行;或DEFAULT
,仅在VALUES
表达式由于您无法在此处使用VALUES(DEFAULT, ...)
,因此您唯一的选择是省略INSERT
列列表中的列:
regress=# create table test (id serial primary key, name varchar(50));
CREATE TABLE
regress=# insert into test(name) select name from json_populate_record(NULL::test, '{"name": "John"}');
INSERT 0 1
是的,这意味着您必须列出列。实际上,一次在SELECT
列表中,一次在INSERT
列列表中。
为了避免需要这个PostgreSQL需要一种方法来指定DEFAULT
作为记录的值,所以json_populate_record
可以返回DEFAULT
而不是NULL
}对于未定义的列。这可能不是您对所有列的意图,并且当DEFAULT
在json_populate_record
中使用时,会导致INSERT
如何处理json_populate_record
的问题表达
所以我猜{{1}}可能没有您希望生成密钥的行那么有用。
答案 1 :(得分:10)
继续Craig's answer,您可能需要编写某种存储过程来执行必要的动态SQL,如下所示:
CREATE OR REPLACE FUNCTION jsoninsert(relname text, reljson text)
RETURNS record AS
$BODY$DECLARE
ret RECORD;
inputstring text;
BEGIN
SELECT string_agg(quote_ident(key),',') INTO inputstring
FROM json_object_keys(reljson::json) AS X (key);
EXECUTE 'INSERT INTO '|| quote_ident(relname)
|| '(' || inputstring || ') SELECT ' || inputstring
|| ' FROM json_populate_record( NULL::' || quote_ident(relname) || ' , json_in($1)) RETURNING *'
INTO ret USING reljson::cstring;
RETURN ret;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
然后用
打电话SELECT jsoninsert('test', '{"name": "John"}');