我有一个包含数百万条记录的DB2数据库。我发现一些char()或varchar()字段包含不应存储的特殊字符。我猜应用程序收到了破碎的数据或一些代码。
无论如何,我想找到具有这些破碎数据的记录,这些数据是特殊字符(不是字母)。
我试图找到使用查询的方式,但不能。有人知道好的查询或建议吗?
您可以使用DB2 TRANSLATE()
函数来隔离非字母数字字符。请注意,这在Oracle兼容模式下不起作用,因为在这种情况下,DB2会将空字符串视为NULL,就像Oracle一样。
SELECT *
FROM yourtable
WHERE LENGTH(TRANSLATE(
yourcolumn,
'', -- empty string
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
)) > 0 -- after translating ASCII characters to empty strings
-- there's still something left
我知道这是一个较老的线程...但是看了一眼之后...这是我的确切问题,这是我想出的解决问题行的解决方案......所以我可以进去并手动修复它们。仅供参考 - 我遇到的问题是因为用户正在从Word复制/粘贴到我的应用程序中。是的,我知道我们应该在保存之前解决这个问题......但是我们还有更大的鱼来炸。
SELECT * FROM TABLE_A where ASCII(TRIM(TRANSLATE( COLUMN_A, ' ', -- empty string '()<>!;%$#*?@+&^=-":/''.,0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ))) not in (10,64)
一些说明:
您可以使用正则表达式来检索无效字符。但是这个过程非常昂贵,因为您必须读取所有数据,然后进行处理。
为了在DB2中使用正则表达式,您必须调整环境,因为安装中的SQL不能使用此功能。你有这三个选择:
一旦定义了正则表达式以忽略有效字符(类似于/[^a-zA-Z0-9]/
),就可以在数据库中执行。请记住检索可以检测行的其他列(例如列ID),然后执行更新或删除以删除无效字符。
如果你不知道如何使用正则表达式,这里有一个很好的信息来源:http://www.regular-expressions.info/特别是http://www.regular-expressions.info/charclass.html
关于正则表达式有一个相关的问题:Regular Expressions in DB2 SQL
如果您使用特殊字符表示不可打印的字符,则可以使用以下字符:
select yourfield, hex(trim(yourfield)),TRANSLATE(
yourfield,
' ',
x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
from yourtable
where yourfield <> TRANSLATE(
yourfield,
' ',
x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
你可能会看到你的奇怪人物HEX()
<40。
无论如何,如果您知道奇数/特殊字符的HEX()
,您可以使用此方法,然后将它们替换为空格或任何您想要的永久字符:
Update yourtable
set yourfield= Translate(yourfield,
' ',
x'000102030405060708090A0B0C0D0E101112131415161718191A1B1C1D1E202122232425262728292A2B2C2D2E303132333435363738393A3B3C3D3E0F1F2F3F')
where yourfield <> Translate(yourfield,
' ',
x'000102030405060708090A0B0C0D0E101112131415161718191A1B1C1D1E202122232425262728292A2B2C2D2E303132333435363738393A3B3C3D3E0F1F2F3F')
这个查询过去曾在iSeries DB2上使用过。
select * from db/table where posstr(field, x'3F') > 0
麻烦的是你必须确定你在字符串中搜索的十六进制值。我有一个类似的情况,我确信该字符的十六进制代码是x'3F,但是当我对不可见的字符进行子字符串时,它实际上是x'22。你可能想要挑出给你问题的角色,看看它的价值是什么。
select hex(substr(field, 21,1)) from db/table where posstr(field, 'StringBeforeCharacter') > 0
您可以使用下面的SQL,它可以正常工作。
select col 1 from table where col1 like '%'|| chr(10) || '%';