DB2/iSeries SQL 清理 CR/LF、制表符等

Posted

技术标签:

【中文标题】DB2/iSeries SQL 清理 CR/LF、制表符等【英文标题】:DB2/iSeries SQL clean up CR/LF, tabs etc 【发布时间】:2011-11-26 06:19:05 【问题描述】:

我需要在一组超过 400k 的字符串记录中查找并清理换行符、回车、制表符和“SUB”字符,但是这个 DB2 环境对我造成了影响。

以为我可以用 REPLACE() 和 CHR() 函数进行一些搜索和替换,但似乎 CHR() 在此系统上不可用(错误:*LIBL 类型 *N 中的 CHR 未找到)。使用 \t、\r、\n 等似乎也不起作用。字符可以位于字符串的中间或末尾。

DBMS = DB2
System = iSeries
Language = SQL
Encoding = Not sure, possibly EBCDIC

关于我可以用这个做什么的任何提示?

【问题讨论】:

您可以随时导出数据、处理并放回数据。我以前做过。我使用 Squirrel SQL 将 DB2 表移至 mysql 进行测试,然后再将 DB2 移回生产环境(许多 GB)。使用 squirrel 的问题包括:缺少进度指示,并且需要将整个表保存在内存中,包括 SLQ 标记,因此您需要增加 Java 内存限制。取决于字符串大小,但希望几个 Gig 就足够了。这也必须在本地完成,否则带宽可能会成为问题。 哦,还有一件事......由于关键字和引用的不同,您可能需要应用几个正则表达式才能导入。在一个像样的文本编辑器中确实没有什么搜索和替换不能处理的(假设它可以处理至少 40 万条记录!)哦 Squirrel 甚至会为你编写表定义。 【参考方案1】:

我用这个 SQL 找到了 x'25' 和 x'0D':

SELECT 
     <field>
    , LOCATE(x'0D', <field>) AS "0D" 
    , LOCATE(x'25', <field>) AS "25" 
    , length(trim(<field>)) AS "Length"
FROM <file> 
WHERE   LOCATE(x'25', <field>) > 0 
    OR  LOCATE(x'0D', <field>) > 0 

我用这个 SQL 来替换它们:

UPDATE <file> 
SET <field> = REPLACE(REPLACE(<field>, x'0D', ' '), x'25', ' ')
WHERE   LOCATE(x'25', <field>) > 0 
    OR  LOCATE(x'0D', <field>) > 0 

【讨论】:

适用于任何使用 v5r3 或更高版本的人的好解决方案,这是替换功能所必需的。【参考方案2】:

如果您想清除回车符 (EBCDIC x'0d') 和换行符 (EBCDIC x'25') 等特定字符,您应该找到 translated character in EBCDIC 然后使用 TRANSLATE() 函数将它们替换为空格.

如果您只想删除无法显示的字符,请查找 x'40' 以下的任何内容。

【讨论】:

其实换行是EBCDIC x'25'。 x'0A' 是 ASCII 中的 LF。 很好地解释了它的工作原理,并感谢@FroggyTX 提供了一个实际示例。【参考方案3】:

这是一个示例脚本,将X'41' 替换为X'40'。在我们的商店中造成问题的事情:

UPDATE [yourfile] SET [yourfield] = TRANSLATE([yourfield], X'40', 
X'41') WHERE [yourfield] like '%' concat X'41' concat '%'    

如果您需要替换多个字符,请将“to”和“from”十六进制字符串扩展为 TRANSLATE 函数中所需的值。

【讨论】:

【参考方案4】:

尝试翻译或替换。

蛮力法包括使用 POSITION 查找错误字符,然后在其前后使用 SUBSTR。 CONCAT 两个子字符串(减去不需要的字符)以重新形成列。

字符编码几乎可以肯定是 EBCDIC 字符集之一。根据最初加载表格的方式,CR 可能是 x'0d',LF x'15', x'25'。找到一个简单的方法是打开一个绿屏,然后对着桌子做一个 DSPPFM。按 F10 再按 F11 查看表格是原始的,十六进制(上/下)格式。

【讨论】:

【参考方案5】:

有关可用功能的详细信息,请参阅 DB2 for i5/OS SQL Reference.

【讨论】:

【参考方案6】:

也许TRANSLATE() 函数可以满足您的需求。

    TRANSLATE( data, tochars, fromchars )

...其中 fromchars 是您不想要的字符集,而 tochars 是您想要替换它们的相应字符。您可能必须以十六进制格式将其写出来,如x'nnnnnn...',并且您需要知道您正在使用的字符集。 在您的表上使用DSPFFD 命令应该会显示您的字段的 CCSID。

【讨论】:

【参考方案7】:

我们费了很大劲才从平面文件中替换新行字符和回车。

最后我们使用下面的 sql 对问题进行排序。

REPLACE(REPLACE(COLUMN_NAME, CHR(13), ''), CHR(10), '')

试试看

CR = CHR(13)
LF = CHR(10) 

【讨论】:

以上是关于DB2/iSeries SQL 清理 CR/LF、制表符等的主要内容,如果未能解决你的问题,请参考以下文章

Db2 iseries INSERT ON DUPLICATE KEY

通过 Data Studio 为 DB2 for IBM i (iSeries) 构建存储过程失败

Oracle SQL:如何用 CR/LF 替换现有 VARCHAR2 字段中的字符

C# - 无法将类型“IBM.Data.DB2.iSeries.iDB2DataReader”隐式转换为“System.Data.SqlClient.SqlDataReader”

CR, LF, CR/LF 回车 换行

CR, LF, CR/LF 回车 换行