Replace Informix 9.52C1-更换回车和换行

Replace Informix 9.52C1-更换回车和换行,replace,escaping,informix,Replace,Escaping,Informix,我搜索google,找不到任何真正帮助我在IBM网站上展示Informix 11.5及以上功能的东西,比如他们是否停止支持9.52C1或其他什么。因此我来到这里 正如主题所述,我正在使用Informix 9.52C1。我使用SQL获得了以下信息: SELECT owner FROM systables WHERE TABNAME= ' VERSION'; 我不确定是否支持replace函数,因为在执行语句时: SELECT col1, REPLACE('r','p','poster') as

我搜索google,找不到任何真正帮助我在IBM网站上展示Informix 11.5及以上功能的东西,比如他们是否停止支持9.52C1或其他什么。因此我来到这里

正如主题所述,我正在使用Informix 9.52C1。我使用SQL获得了以下信息:

SELECT owner FROM systables WHERE TABNAME= ' VERSION';
我不确定是否支持replace函数,因为在执行语句时:

SELECT col1, REPLACE('r','p','poster') as col2 FROM table;
col2列只包含字母“r”,但是没有抛出错误,尽管我使用了REPLACE()函数

我知道可以使用“\r\n”转义格式找到转义字符(CRLF),因为此SQL相应地工作:

SELECT *  FROM table WHERE col1 LIKE '%\r\n%';
注意:我使用上面的SQL检索版本号,因为我只能通过客户端DB应用程序进行访问。但是,如果您可以访问运行informix DB服务器的实际主机,我相信会有一些命令参数来解析版本,可能是DB服务器应用程序的default linux--version或-v参数

这确实只返回了包含CRLF的记录

我的主要工作是在将数据从Informix 9.52C1迁移到PostgreSQL数据库时,在CR和LF前面加一个反斜杠。我计划使用COPY函数将数据加载到PostgreSQL数据库中,COPY函数的工作方式与我做测试记录时的工作方式相同。我的困境是以正确的格式从Informix中提取数据。有人能帮助解决这个问题吗

我试过:

SELECT REPLACE('\\\r\\\n','\r\n',col1) as description FROM table;
但是,我认为由于replace函数的缘故,这不起作用,正如我提到的,我不确定replace函数在这个Informix版本中是否可用

提前感谢,

杰格


另外,ASCII()、CHAR()和CHR()函数都不起作用。一些网站建议这些功能。但据我所知,函数CHR()&ASCII()是在verison 11.5+中实现的。这建议使用函数。

要在数据库之间迁移数据,可以使用JDBC驱动程序(我使用Jython,但Java或其他可以使用JDBC驱动程序的语言就可以了),然后从源数据库(Informix)中选择…,然后插入…将数据读入目标(PostgreSQL)。使用BatchInsert或PreparedStatement,速度非常快。在我的代码中,它看起来像:

insert_str = 'INSERT INTO ' + table_name + ' (' + column_names + ') VALUES (' + question_marks + ')'
insert_stmt = db_to.prepareStatement(insert_str)
...
pstm2 = db_from.createStatement()
rs_in = pstm2.executeQuery('SELECT %s FROM %s %s' % (column_names, table_name, order_str))
...
while (rs_in.next()):
    for i in range(1, col_count + 1):
        insert_stmt.setObject(i, rs_in.getObject(i))
当然,您必须注意错误、自动提交、获取大小等,但我认为这是值得您努力的


您的
COPY…
创意也不错。您是否将Informix的输出保存在文本文件中?如果是文本文件,您只需在将文本文件导入PostgreSQL之前更正它。

我不认识9.52C1版本。Informix版本可能是9.52.UC1—可以从
U
F
W
H
T
中选择第一个字母。但是,主要的版本号是9.00..9.03,9.10..9.16,9.20,9.21,9.30,9.40,10.00,11.10,11.50,11.70,12.10-在一个版本中不包括9和5的序列。嗯,在很多方面,这并不重要;任何9.x版本都已经失去支持十年了,如果不是更长的话,也不应该继续使用

假设现在还没有升级到Informix的现代版本,那么您必须实现自己的功能。要完成这项工作,最好用C实现它们,并将它们作为UDR(用户定义例程)包安装在共享库中。那会给你最好的表现。假设这是不可行的(我手头上没有一组这样的函数,但编写它们应该不难),那么您就不得不求助于SPL(存储过程语言)例程。由于SPL w.r.t子字符串操作的限制,这些操作的速度并不快,特别是带有
[]
符号的内置子字符串操作不接受变量作为下标。礼貌地说,这真的很痛苦

下面是一个版本的
char\u at
,它在给定位置获取最多255个字符的字符串中的单个字符:

-- @(#)$Id: char_at.spl,v 1.1 1999/05/17 23:59:59 jleffler Exp $
--
-- CHAR_AT stored procedure, to return character at given position in string
--
-- Author: J Leffler
-- Date: 1999-05-17

CREATE PROCEDURE char_at(str VARCHAR(255), pos SMALLINT) RETURNING CHAR(1);

    DEFINE c CHAR(1);

    IF pos > LENGTH(str) OR pos <= 0 THEN
        LET c = NULL;
    ELIF pos <= 16 THEN
        IF   pos =  1 THEN LET c = str[ 1];
        ELIF pos =  2 THEN LET c = str[ 2];
        ELIF pos =  3 THEN LET c = str[ 3];
        ELIF pos =  4 THEN LET c = str[ 4];
        ELIF pos =  5 THEN LET c = str[ 5];
        ELIF pos =  6 THEN LET c = str[ 6];
        ELIF pos =  7 THEN LET c = str[ 7];
        ELIF pos =  8 THEN LET c = str[ 8];
        ELIF pos =  9 THEN LET c = str[ 9];
        ELIF pos = 10 THEN LET c = str[10];
        ELIF pos = 11 THEN LET c = str[11];
        ELIF pos = 12 THEN LET c = str[12];
        ELIF pos = 13 THEN LET c = str[13];
        ELIF pos = 14 THEN LET c = str[14];
        ELIF pos = 15 THEN LET c = str[15];
        ELIF pos = 16 THEN LET c = str[16];
        END IF;
    ELIF pos <=  32 THEN LET c = char_at(str[ 17, 32], pos -  1 * 16);
    ELIF pos <=  48 THEN LET c = char_at(str[ 33, 48], pos -  2 * 16);
    ELIF pos <=  64 THEN LET c = char_at(str[ 49, 64], pos -  3 * 16);
    ELIF pos <=  80 THEN LET c = char_at(str[ 65, 80], pos -  4 * 16);
    ELIF pos <=  96 THEN LET c = char_at(str[ 81, 96], pos -  5 * 16);
    ELIF pos <= 112 THEN LET c = char_at(str[ 97,112], pos -  6 * 16);
    ELIF pos <= 128 THEN LET c = char_at(str[113,128], pos -  7 * 16);
    ELIF pos <= 144 THEN LET c = char_at(str[129,144], pos -  8 * 16);
    ELIF pos <= 160 THEN LET c = char_at(str[145,160], pos -  9 * 16);
    ELIF pos <= 176 THEN LET c = char_at(str[161,176], pos - 10 * 16);
    ELIF pos <= 192 THEN LET c = char_at(str[177,192], pos - 11 * 16);
    ELIF pos <= 208 THEN LET c = char_at(str[193,208], pos - 12 * 16);
    ELIF pos <= 224 THEN LET c = char_at(str[209,224], pos - 13 * 16);
    ELIF pos <= 240 THEN LET c = char_at(str[225,240], pos - 14 * 16);
    ELIF pos <= 255 THEN LET c = char_at(str[241,255], pos - 15 * 16);  -- Note asymmetry in upper bound!
    ELSE                 LET c = NULL;  -- Not reached!
    END IF;

    RETURN c;

END PROCEDURE;
其中需要一个表:

-- @(#)$Id: asciitbl.sql,v 1.2 2005/03/30 17:51:12 jleffler Exp $
--
-- @(#)Create ASCII Table (for ASCII and CHR functions).

CREATE TABLE ascii
(
    val     INTEGER NOT NULL UNIQUE CONSTRAINT u1_ascii,
    chr     CHAR(1) NOT NULL UNIQUE CONSTRAINT u2_ascii
);
REVOKE ALL ON ascii FROM PUBLIC;
GRANT SELECT ON ascii TO PUBLIC;
以及要放入其中的数据-255行,例如:

…
32| 
33|!
34|"
35|#
36|$
37|%
38|&
39|'
40|(
…
64|@
65|A
66|B
67|C
68|D
69|E
…

您应该能够在http://www.ascii.com.cn.cn上找到这段代码的副本,名称为ascii

,如果有人偶然发现这个问题,请查看答案。我的解决方案是将卸载文件放入十六进制编辑器中,并将CRLF(0x0A0D)替换为“\r\n”(0x5C725C6E)。在看到过时的informix db的局限性后,我按照主管的指示这样做了。但是,任何人都可以尝试下面的两个答案。我没有试过,因为我已经有机会了,这个问题对我来说已经解决了。谢谢乔纳森,我会记住这一点。目前我只迁移一个系统的数据,幸运的是只有一个表有这种情况。我的经理已经告诉我,我们将只使用一个十六进制编辑器或一些工具来进行查找和替换。我还没有尝试过你上面的SQLs,但是如果我觉得有必要,我会知道去哪里。谢谢Michal,当我们移动我们的核心系统时,我告诉了我的经理这一点,我们的核心系统包含了我目前正在做的大约10倍的内容。我告诉他,我们应该使用程序,因为它使您能够在加载数据库之前操作数据。谢谢你的回复。
…
32| 
33|!
34|"
35|#
36|$
37|%
38|&
39|'
40|(
…
64|@
65|A
66|B
67|C
68|D
69|E
…