如何在DB2中查找特殊字符?

如何在DB2中查找特殊字符?,db2,special-characters,Db2,Special Characters,我有一个包含数百万条记录的DB2数据库。 我发现一些char或varchar字段包含不应该存储的特殊字符。 我猜应用程序收到了损坏的数据或一些代码 无论如何,我想找到有这些坏数据的记录,这些数据是特殊字符,而不是字母 我试图找到使用查询的方法,但没有找到。 有人知道好的查询或建议吗?您可以使用正则表达式来检索无效字符。然而,这个过程非常昂贵,因为您必须读取所有数据,然后对其进行处理 为了在DB2中使用正则表达式,您必须适应环境,因为在安装过程中SQL无法使用此功能。您有以下三种选择: 将正则表达

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

无论如何,我想找到有这些坏数据的记录,这些数据是特殊字符,而不是字母

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

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

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

将正则表达式与xQuery而不是普通SQL结合使用。 定义本文所述的外部C存储过程: 如果您不了解Japanese,这里有一篇很好的文章解释如何在xQuery中使用RegEx,您只能下载源代码并安装它们。通过几个拉丁字符的例子,我想你们可以理解如何使用这个。 一旦定义了一个正则表达式来忽略有效字符,比如/[^a-zA-Z0-9]/,就可以在数据库中执行。请记住检索可以检测行的其他列(例如列ID),然后执行更新或删除以删除无效字符

如果您不知道如何使用正则表达式,这里有一个很好的信息来源:特别是

关于正则表达式还有一个相关的问题:

您可以使用DB2 TRANSLATE函数来隔离非字母数字字符。请注意,这在Oracle兼容模式下不起作用,因为在这种情况下,DB2将像Oracle一样将空字符串视为null

SELECT *
FROM yourtable
WHERE LENGTH(TRANSLATE(
  yourcolumn,
  '', -- empty string
  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
)) > 0 -- after translating ASCII characters to empty strings 
       -- there's still something left

我知道这是一个较旧的线程…但在阅读了大量内容之后…这就是我的问题,这里是我提出的解决方案,用于确定问题行…以便我可以进入并手动修复它们。仅供参考-我遇到的问题是因为用户正在将Word复制/粘贴到我的应用程序中。是的,我知道我们应该在存钱之前解决这个问题……但我们还有更重要的事情要做

从表A中选择* 在哪里翻译 A栏, ''-空字符串 '!;%$*?@+&^=-:/.,0123456789ABCDEFGHIjklmnopqrstuvxyzABCDEFGHIjklmnopqrstuvxyz' 不是在10,64

一些注意事项:

我们使用iSeries DB2,这非常有效 确保translate函数中的所有空格都保持不变…您使用的每个字符都需要1个空格 在translate函数的第三个参数中,有两个单引号彼此相邻,对于那些可能不知道的人,第一个单引号只是转义另一个单引号
如果特殊字符是指不可打印的字符,则可以使用以下字符:

select yourfield, hex(trim(yourfield)),TRANSLATE(
  yourfield,
  ' ', 
  x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')
from yourtable
where yourfield <> TRANSLATE(
  yourfield,
  ' ', 
  x'000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F')

这个查询过去在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,这将很好地工作


从col1类似于“%”| | chr10 | |“%”的表中选择col1

那么你将如何处理记录中的这些字符呢?看起来你在假设一个LUW环境,嗯z/OS和IBMi很可能在EBCDIC中工作。但这只会影响你的评论,查询是可移植的。但实际上,我认为你指的是非字母字符,或者可能应该是非字母数字。ASCII和EBCDIC包含许多非字母数字甚至非可显示字符的代码点。CR和LF都是简单的例子,很有效!谢谢你,穆斯塔西奥。另外,我的字段有一些空白字段,所以我使用函数LENGTHTRIMTRANSLATE。上面的翻译示例有一个拼写错误abcdefj':j->g;检查是否有人使用该代码。祝您今天过得愉快!什么表示“不在10和64中”,我知道出于某种原因,代码返回的64是空字符串,但什么是10?。谢谢你的回答。10可能是一个换行符。他有一张马车的回程票,要找的话有13张。这个答案完全帮助了我。用类似的方法保留任何数字的正确方法是什么。当我运行这个程序时,我删除了所有的内容,包括数字。您能告诉我为什么应该这样做吗?在哪个DB2版本中?显示x'…'部分显示一组正方形和矩形,后跟!$%&'*+,-/0123456789:; 我无法复制。正如所料,当myfields包含字母表时,它无法翻译。所以,我猜十六进制缺少很多pri 可恶的人物?不切实际,如果我们必须找到所有可打印的字符放入该引用。
select hex(substr(field, 21,1)) from db/table where posstr(field, 'StringBeforeCharacter') > 0