我有一个包含数百万条记录的 DB2 数据库。我发现某些 char() 或 varchar() 字段包含不应存储的特殊字符。我猜应用程序收到了损坏的数据或某些代码成功了。
无论如何,我想找到包含这些损坏数据的记录,这些数据是特殊字符(不是字母)。
我试图找到使用查询的方式,但找不到。有人知道好的查询或建议吗?
我有一个包含数百万条记录的 DB2 数据库。我发现某些 char() 或 varchar() 字段包含不应存储的特殊字符。我猜应用程序收到了损坏的数据或某些代码成功了。
无论如何,我想找到包含这些损坏数据的记录,这些数据是特殊字符(不是字母)。
我试图找到使用查询的方式,但找不到。有人知道好的查询或建议吗?
您可以使用 DB2TRANSLATE()
函数来隔离非字母数字字符。请注意,这在 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) || '%';