如何使用json插入具有非空列的表?
我正在尝试使用以下命令插入具有多个非空默认列的表如何使用json插入具有非空列的表?,json,postgresql,plpgsql,postgresql-9.6,node-postgres,Json,Postgresql,Plpgsql,Postgresql 9.6,Node Postgres,我正在尝试使用以下命令插入具有多个非空默认列的表food: food_insertone('{“id”:1,“taste”:“sweet”}'::JSON) food_insertone(“{”id:2}”::JSON) food_insertone('{“id”:3,“taste:null}'::JSON) 结果应该是: INSERTED 1, 'sweet' INSERTED 2, '' ERROR (null not allowed in taste) 表食品定义如下: CREATE
food
:
food_insertone('{“id”:1,“taste”:“sweet”}'::JSON)
food_insertone(“{”id:2}”::JSON)
food_insertone('{“id”:3,“taste:null}'::JSON)
INSERTED 1, 'sweet'
INSERTED 2, ''
ERROR (null not allowed in taste)
表食品定义如下:
CREATE TABLE "food" (
"id" INT,
"taste" TEXT NOT NULL DEFAULT '',
...
);
CREATE OR REPLACE FUNCTION "food_insertone" (JSON)
RETURNS VOID AS $$
INSERT INTO "food" SELECT * FROM json_populate_record(NULL::"food", $1);
$$ LANGUAGE SQL;
我试图插入如下内容:
SELECT food_insertone('{"id": 1}'::JSON);
但这不起作用,给了我一个错误:
null value in column "taste" violates not-null constraint
我知道json\u populate\u record()
为json中未提及的列创建空值,这导致插入空值,从而导致此错误。普通插入可以工作,但这是一个动态表。要使用默认值simple case:
t=# create table food(id int, t text not null default 'some');
CREATE TABLE
t=# insert into food(id) SELECT id FROM json_populate_record(NULL::"food", '{"id":0}');
INSERT 0 1
t=# select * from food ;
id | t
----+------
0 | some
(1 row)
使用coalesce和其他值:
t=# insert into food(id,t)
SELECT id,coalesce(t,'some simple other value')
FROM json_populate_record(NULL::"food", '{"id":0}');
当然,您可以使用一些可怕的方法来获得实际的默认值:
t=# insert into food(id,t) SELECT id,coalesce(t,rtrim) FROM json_populate_record(NULL::"food", '{"id":0}') join (select rtrim(ltrim(split_part(column_default,'::',1),$$'$$),$$'$$) from information_schema.columns where table_name = 'food' and column_name = 't') dflt on true;
INSERT 0 1
t=# select * from food ;
id | t
----+-------------------------
0 | some simple other value
0 | some
(2 rows)
请用普通的insert显示insert语句,我的意思是在这个特殊情况下类似于insert INTO“food”(id)VALUES(1)
,但是这个表有多个这样的列。如果json中没有指定,我只想使用默认值,但是仍然不允许空值。是否可以使用表的一行默认值从json\u populate\u record()
中提取行值?但是如果提供了t
的值,我还想插入它(只要它不是空值).我认为你的怪诞方式是最好的,因为我之前不知道列或它们的默认值(我使用alter
添加列)。但我不明白它是干什么的,你能解释一下吗?我想a还有另一个可怕的方法:1。要将默认值获取为json(选择json_object_agg(column_name,column_default)::JSONB FROM information_schema.columns其中(table_schema,table_name)=('public',food');
).2。然后,我可以将其附加到原始输入json中,并执行json_populate_record(),这应该是可行的。谢谢。我想你多放了一些美元,这不是命令的一部分。我知道需要删除类型转换。我现在正在使用这个查询,它可以工作:CREATE或REPLACE函数“table\u default”(TEXT)将JSON作为$$SELECT JSON\u object\u agg(column\u name,REPLACE(split\u part(column\u default,,::',1),E'\'')从信息模式返回。columns其中(table\u schema,table\u name)=('public',1);$语言SQL严格不可变代码>。