我有一个大型数据库,其中包含用JSON编写的分析数据.
我想过滤掉数据不正确的行:
'{"hello": "world''{"products": [1,2,3]}'并将遗漏'{"products": 1}'我想做那样的事情:
select * 
from analytics 
where (is_correct_json(json::json)) 
and (is_array(json::json->>'products'))
我怎样才能做到这一点?
a_h*_*ame 17
这是另一个很好的例子,为什么从一开始就选择适当的数据类型有助于以后;)
没有内置函数来检查给定文本是否是有效的JSON.但是你可以写自己的:
create or replace function is_valid_json(p_json text)
  returns boolean
as
$$
begin
  return (p_json::json is not null);
exception 
  when others then
     return false;  
end;
$$
language plpgsql
immutable;
注意:由于异常处理,这不会很快.如果你在许多无效值上调用它,这将大大减慢你的选择速度.
但是两者'{"products": 1}'并'{"products": [1,2,3]}'是有效的JSON文档.前者无效的事实是基于您的应用程序逻辑,而不是基于JSON语法.
要验证您是否需要类似的功能,请在调用时捕获错误 json_array_length()
create or replace function is_valid_json_array(p_json text, p_element text)
  returns boolean
as
$$
begin
  return json_array_length( p_json::json -> p_element) >= 0;
exception 
  when others then
     return false;  
end;
$$
language plpgsql
immutable;
Erw*_*ter 12
IS JSONPostgres 16(发布日期为 2023 年末)最终为此目的实现了 SQL/JSON 标准谓词。手册:
该谓词测试是否
expression可以解析为 JSON(可能是指定类型)。如果指定了SCALARorARRAY或OBJECT,则测试 JSON 是否属于该特定类型。如果WITH UNIQUE KEYS指定,则expression还将测试 中的任何对象以查看它是否具有重复的键。
要验证该字符串是有效的 JSON 文字:
... WHERE string_column IS JSON
要验证该字符串是有效的 JSON 数组文字:
... WHERE string_column IS JSON ARRAY
(但请注意,这'{"products": [1,2,3]}'不是一个 JSON 数组,而是一个 JSON 对象。)
这是a_horse_with_no_name 函数的改进版本,仍然使用昂贵的子事务来捕获invalid_text_representation错误。但它应该更快、更安全:
... WHERE string_column IS JSON
标记该函数STRICT以获得更快的null输入结果。
第一项也使其在功能上有所不同,返回null输入null- 这实际上就是修饰符的STRICT作用,RETURNS NULL ON NULL INPUT是相同的替代语法。这看起来更合理,因为null对于类型json和jsonb(或 Postgres 中的任何数据类型)有效,我们可以根据需要测试true/ false/ null。
PARALLEL SAFE遗憾的是,我们无法在 Postgres 9.6 或更高版本中标记该函数。该EXCEPTION部分使 Postgres 在输入函数时启动子事务,这与并行执行不兼容。有关的:
此函数仅捕获“无效的文本表示”,而不捕获任何其他错误 - 即使其他错误似乎几乎不可能。
“f_is_json”只是我的命名约定,在自定义函数前加上“f_”前缀,以清楚地区分内置函数。
快速测试:
... WHERE string_column IS JSON ARRAY
| 归档时间: | 
 | 
| 查看次数: | 4936 次 | 
| 最近记录: |