在这里运行PostgreSQL 9.2.8 ......
我一直在尝试获取表格中包含非ASCII字符的所有行的列表 - 超出<space>
到~
范围内的任何行,以及反引号字符`
。如果任何行包含任何无效字符,则将显示包含所有地址值的行。但由于某种原因,我收到以下错误:
ERROR: argument of OR must not return a set (10586)
LINE 9: (CAST(regexp_matches(a.address_line_1,'([^ !-~]|`)') AS VARCHAR)...
^
********** Error **********
ERROR: argument of OR must not return a set (10586)
SQL state: 42804
Character: 252
我一直试图使用的查询如下:
select a.address_id, a.address_line_1,
a.address_line_2,
a.address_line_3,
regexp_matches(a.address_line_1,'([^ !-~]|`)'),
regexp_matches(a.address_line_2,'([^ !-~]|`)'),
regexp_matches(a.address_line_3,'([^ !-~]|`)')
FROM public.address a
WHERE
(CAST(regexp_matches(a.address_line_1,'([^ !-~]|`)') AS VARCHAR) <> '') OR
(CAST(regexp_matches(a.address_line_2,'([^ !-~]|`)') AS VARCHAR) <> '') OR
(CAST(regexp_matches(a.address_line_3,'([^ !-~]|`)') AS VARCHAR) <> '')
LIMIT 1000
我不确定我可能会遗漏什么,因为这似乎是一个有效的查询。
我正在尝试获取三个地址字段中任何一个中存在无效字符的行,而不仅仅是三个地址字段中的无效字符。
答案 0 :(得分:1)
regexp_matches()返回SETOF text
,无法像您尝试的那样使用(正如错误消息所示)。您可以使用regular expression operator ~
代替。
但是你的正则表达式似乎没有涵盖你所描述的内容:
地址中的非ASCII字符
此外,括号表达式!-~
中的范围[^ !-~]
取决于您的COLLATION
设置。 The manual warns:
范围非常依赖于整理顺序,因此便携式程序应该避免依赖它们。
考虑:
SELECT g, chr(g), chr(g) ~ '([^ !-~]|`)'
FROM generate_series (1,300) g; -- ASCII range plus some
假设服务器编码UTF8,找到3列中包含任何非ASCII字符的行:
...
WHERE octet_length(concat(a.address_line_1, a.address_line_2, a.address_line_3))
<> length(concat(a.address_line_1, a.address_line_2, a.address_line_3))
这是有效的,因为所有非ASCII字符在UTF8中编码的字节数超过1个,因此octet_length()
报告的数字高于length()
(别名:char_length()
)。与concat()
的连接可以防止可能的NULL值。
要测试反引号,请添加:
...
OR concat(a.address_line_1, a.address_line_2, a.address_line_3) LIKE '%`%'
答案 1 :(得分:0)
一种方法使用exists
:
where exists (select 1 from regexp_matches(a.address_line_1, '[^ !-~]')) or
exists (select 1 from regexp_matches(a.address_line_2, '[^ !-~]')) or
exists (select 1 from regexp_matches(a.address_line_3, '[^ !-~]'))
或者更简单:
where a.address_line_1 ~ '[^ !-~]' or
a.address_line_2 ~ '[^ !-~]' or
a.address_line_3 ~ '[^ !-~]'