在Postgresql中使用CHECK约束验证json字符串)

时间:2014-01-27 04:47:37

标签: sql json constraints postgresql-9.3

我有一个以下架构的表格:

CREATE TABLE tbl_name (
id bigserial primary key,
phone_info json
);

phone_info列的示例json数据如下所示。

 {  
   "STATUS":{"1010101010":"1","2020202020":"1"},
   "1010101010":"OK", 
   "2020202020":"OK"  
 }

现在我需要在phone_info列上添加一个检查约束,以便“STATUS”的所有键即(1010101010,2020202020)应作为(key,value)对phone_info列存在,其中value为“OK”。 因此,上面的示例数据将满足检查约束,因为phone_info列中存在以下键值对。

"1010101010":"OK"
"2020202020,":"OK" 

我已尝试过以下解决方案,但由于检查约束不支持array_agg函数,因此无效。

ALTER TABLE tbl_name
ADD CONSTRAINT validate_info CHECK ('OK' = ALL(array_agg(phone_info->json_object_keys(phone_info->'STATUS'))) ); 

有人可以帮帮我,我可以写一个SQL函数并在check约束中使用该函数吗?

1 个答案:

答案 0 :(得分:2)

有了这样的话,我想你会想要一个SQL函数。

CREATE TABLE tjson AS SELECT '{  
   "STATUS":{"1010101010":"1","2020202020":"1"},
   "1010101010":"OK", 
   "2020202020":"OK"  
 }'::json AS col;

可能是这样的:

CREATE OR REPLACE FUNCTION my_json_valid(json) RETURNS boolean AS $$
SELECT bool_and(coalesce($1->>k = 'OK','f'))
FROM json_object_keys($1->'STATUS') k;
$$ LANGUAGE sql IMMUTABLE;

...但请记住,虽然PostgreSQL允许您修改该功能,但这样做会导致以前有效的行在表中失效。切勿在不删除约束的情况下修改此函数,然后再将其添加回来。