2

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

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)应该作为 phone_info 列的(键,值)对存在,其中值将是“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 函数并在检查约束中使用该函数吗?

4

1 回答 1

3

有了这样的东西,我想你会想要一个 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 将允许您修改该函数,但这样做会导致以前有效的行在表中变得无效。永远不要修改这个函数而不删除约束然后重新添加它。

于 2014-01-27T09:20:11.553 回答