在postgresql中处理Unicode序列

Lix*_*Lix 31 postgresql unicode json

我在postgresql数据库(9.4.1)中的JSON(不是JSONB)列中存储了一些JSON数据.其中一些JSON结构在其属性值中包含unicode序列.例如:

{"client_id": 1, "device_name": "FooBar\ufffd\u0000\ufffd\u000f\ufffd" }
Run Code Online (Sandbox Code Playgroud)

当我尝试查询此JSON列时(即使我没有直接尝试访问该device_name属性),我收到以下错误:

错误:不支持的Unicode转义序列
详细信息:\u0000无法转换为文本.

您可以通过在postgresql服务器上执行以下命令来重新创建此错误:

select '{"client_id": 1, "device_name": "FooBar\ufffd\u0000\ufffd\u000f\ufffd" }'::json->>'client_id'
Run Code Online (Sandbox Code Playgroud)

这个错误对我有意义 - 根本没有办法NULL在文本结果中表示unicode序列.

有没有办法让我查询相同的JSON数据而不必对传入的数据执行"卫生"?这些JSON结构会定期更改,因此扫描特定属性(device_name在本例中)将不是一个好的解决方案,因为可能很容易存在可能包含类似数据的其他属性.


经过一些调查后,似乎这个行为对于版本9.4.1是新的,如更改日志中所述:

...因此\u0000,当需要转换为转义形式时,现在也会在json值中被拒绝.\u0000只要没有对值进行处理,此更改不会破坏存储在json列中的能力...

这真的是意图吗?降级到9.4.1之前是否可行?


作为旁注,此属性取自客户端移动设备的名称 - 它是将此文本输入设备的用户.用户如何插入NULLREPLACEMENT CHARACTER重视?!

Pat*_*ick 32

\u0000是一个在字符串中无效的Unicode代码点.除了消毒字符串之外别无他法.

由于json它只是特定格式的字符串,因此您可以使用标准字符串函数,而无需担心JSON结构.删除代码点的单行清理程序将是:

SELECT (regexp_replace(the_string::text, '\\u0000', '', 'g'))::json;
Run Code Online (Sandbox Code Playgroud)

但是你也可以插入你喜欢的任何字符,如果将零代码点用作某种形式的分隔符,这将是有用的.

还要注意数据库中存储的内容与呈现给用户的方式之间的细微差别.您可以将代码点存储在JSON字符串中,但在将值作为json数据类型处理之前,必须将其预处理为其他字符.

  • Null 在 JSON 字符串中是完全可以接受的,这是否意味着 PostgreSQL 的 JSON 实现有问题?因为它无法处理所有 JSON 格式 (8认同)
  • 使用9.6测试,您也可以使用`replace`而不是正则表达式版本,例如`select replace('{"a":"null\u0000 word\u0000 escape"}','\ u0000',''): :json - >>'a'成功;` (2认同)