7

我有一个包含数百万条记录的 DB2 数据库。我发现某些 char() 或 varchar() 字段包含不应存储的特殊字符。我猜应用程序收到了损坏的数据或某些代码成功了。

无论如何,我想找到包含这些损坏数据的记录,这些数据是特殊字符(不是字母)。

我试图找到使用查询的方式,但找不到。有人知道好的查询或建议吗?

4

6 回答 6

18

您可以使用 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
于 2013-07-04T12:01:22.793 回答
8

我知道这是一个较旧的线程...但是在阅读了大量内容之后...这是我的确切问题,这是我想出的确定问题行的解决方案...这样我就可以进去手动修复它们. 仅供参考 - 我的问题是因为用户正在从 Word 复制/粘贴到我的应用程序中。是的,我知道我们应该在保存之前解决这个问题……但我们有更大的鱼要炸。

SELECT * FROM TABLE_A where ASCII(TRIM(TRANSLATE( COLUMN_A, ' ', -- empty string '()<>!;%$#*?@+&^=-":/''.,0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ))) not in (10,64)

一些注意事项:

  • 我们使用 iSeries DB2,效果很好
  • 确保在翻译功能中保持所有空格完好无损......您使用的任何字符都需要 1 个空格
  • 在 translate 函数的第三个参数中,有 2 个单引号彼此相邻,第一个单引号只是转义另一个(对于那些可能不知道的人)
于 2014-12-09T17:04:15.113 回答
2

您可以使用正则表达式来检索无效字符。但是这个过程非常昂贵,因为您必须读取所有数据,然后对其进行处理。

为了在 DB2 中使用正则表达式,您必须适应环境,因为安装中的 SQL 无法使用此功能。您有以下三个选项:

一旦您定义了一个正则表达式来忽略有效字符(例如/[^a-zA-Z0-9]/),您就可以在数据库中执行。请记住检索可以检测到行的其他列(例如列 ID),然后执行更新或删除以修剪无效字符。

如果您不知道如何使用正则表达式,这里有一个很好的信息来源:http ://www.regular-expressions.info/特别是http://www.regular-expressions.info/charclass.html

有一个关于正则表达式的相关问题:Regular Expressions in DB2 SQL

于 2013-07-04T10:15:27.120 回答
2

如果特殊字符是指不可打印的字符,则可以使用以下字符:

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')
于 2015-06-22T17:01:36.193 回答
-1

这个查询过去曾在 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 
于 2018-01-23T20:04:17.893 回答
-2

您可以使用下面的 SQL,它可以正常工作。

select col 1 from table where col1 like '%'|| chr(10) || '%';

于 2018-05-07T01:58:11.037 回答