如何使用ODBC从Informix中的varchar列获取尾随空格

时间:2009-01-21 09:25:52

标签: odbc informix varchar

我无法从Informix数据库中的varchar列获取尾随空格。

我创建了测试表,用带有一些尾随空格的字段填充它, 但它们不会被SELECT返回,而它们似乎存储在db中。

CREATE TABLE tmptable (txt varchar(240));
INSERT INTO tmptable (txt) VALUES ('123   ');
SELECT txt, txt || '***', LENGTH(txt) FROM tmptable;

我得到了字段:

1: '123' : no trailing spaces!!!
2: '123   ***' : it seems that spaces are stored!!!
3: 3 : LENGTH() do not count trailing spaces!!!

我测试的其他数据库:Oracle和PostgreSQL返回varchar字段 有尾随空格。我试过RPAD()但没有成功。有没有办法得到 尾随空格?

服务器:IBM Informix Dynamic Server版本11.50.TC2DE

客户端:使用ISA(HTML页面源中没有空格)和ODBC驱动程序3.50.TC3DE进行测试

修改 简单的Python测试程序(在Windows上使用ActivePytnon 2.6测试,您必须在最后几行更改连接字符串)

import odbc

def test_varchar(db_alias, dbname):
    print
    print
    arr = db_alias.split('/')
    print '%s    %s' % (arr[0], dbname)
    print '--------------'
    connection = odbc.odbc(db_alias)
    try:
        cursor = connection.cursor()
        cursor.execute("DELETE FROM tmptable;")
        cursor.execute("INSERT INTO tmptable (txt) VALUES ('   %s   ')" %  (dbname))
        #cursor.commit()
        cursor.execute("SELECT txt, txt || '***', LENGTH(txt) FROM tmptable;")
        for row in cursor.fetchall():
            print '[%s]\t[%s]\t[%s]' % (row[0], row[1], row[2])
    finally:
        connection.close()

#test_varchar('database/user/passwd',   'DBproducer')
test_varchar('oracledb/usr/passwd',     'Oracle    ')
test_varchar('informixdb/usr/passwd',   'Informix  ')
test_varchar('postgresqldb/usr/passwd', 'PostgreSQL')

结果:

c:\tools\pyscripts\scripts\db_examples>test_odbc.py
oracledb    Oracle
--------------
[   Oracle       ]      [   Oracle       ***]   [16]


informixdb    Informix
--------------
[   Informix]   [   Informix     ***]   [11]


postgresqldb    PostgreSQL
--------------
[   PostgreSQL   ]      [   PostgreSQL   ***]   [16]

使用JDBC在Jython中的类似程序:

  • 有效(不修剪尾随空格) 使用本机JDBC驱动程序
  • 不起作用 (使用JDBC-ODBC修剪尾随spacec) 桥

来源:

# for Jython 2.5 invoke with --verify
# beacuse of bug: http://bugs.jython.org/issue1127

import sys
from com.ziclix.python.sql import zxJDBC

def test_varchar(driver, db_url, usr, passwd):
    arr = db_url.split(':', 2)
    dbname = arr[1]
    if dbname == 'odbc':
        dbname = db_url
    print "\n\n%s\n--------------" % (dbname)
    try:
        connection = zxJDBC.connect(db_url, usr, passwd, driver)
    except:
        ex = sys.exc_info()
        s = 'Exception: %s: %s\n%s' % (ex[0], ex[1], db_url)
        print s
        return
    cursor = connection.cursor()
    cursor.execute("SELECT txt, txt || '***', LENGTH(txt) FROM tmptable")
    for row in cursor.fetchall():
        print '[%s]\t[%s]\t[%s]' % (row[0], row[1], row[2])


#test_varchar(driver, db_url, usr, passwd)
test_varchar("org.postgresql.Driver", 'jdbc:postgresql://127.0.0.1/pg_testdb', 'postgres', 'postgres')
test_varchar("oracle.jdbc.driver.OracleDriver", 'jdbc:oracle:oci:@MNTEST', 'user', 'passwd')
test_varchar("com.informix.jdbc.IfxDriver", 'jdbc:informix-sqli://127:0:0:1:9088/test_td:informixserver=ol_mn;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250', 'user', 'passwd')

# db_url = jdbc:odbc:[ODBC source name]
test_varchar("sun.jdbc.odbc.JdbcOdbcDriver", 'jdbc:odbc:inf_test_db_odbc', 'user', 'passwd')
test_varchar("sun.jdbc.odbc.JdbcOdbcDriver", 'jdbc:odbc:ora_testdb_odbc', 'user', 'passwd')
test_varchar("sun.jdbc.odbc.JdbcOdbcDriver", 'jdbc:odbc:pg_testdb_odbc', 'postgres', 'postgres')

结果(仅适用于Informix):

C:\tools\pyscripts\scripts\db_examples>jython --verify test_jdbc2.py


informix-sqli
--------------
[   Informix     ]      [   Informix     ***]   [11]


jdbc:odbc:inf_test_db_odbc
--------------
[   Informix]   [   Informix     ***]   [11]

2 个答案:

答案 0 :(得分:0)

在ESQL / C中,当然可以从VARCHAR列获取尾随空格;我的SQLCMD程序(可从IIUG Software Archive获得)完成。但是,必须非常小心地为保存结果的变量使用正确的类型。默认情况下,各种char类型被视为CHAR而不是VARCHAR,并且库会从CHAR值中删除尾随空白,除非您另行指示(否则当您执行指示时空白填充为全长)。

关于ISA:我不知道你是如何确定它返回的。我不会因为失去尾随的空白而感到惊讶。类似的评论将适用于DB-Access。

关于ODBC:请问您能否展示代码,因为虽然代码中可能存在错误(感谢您提供版本信息 - 但它有所帮助,并向我保证,您实际上是最新的你的系统),你写的代码更有可能使用它。

关于LENGTH():它被定义为在计算长度之前删除尾随空白;它总是将其参数视为CHAR值而不是VARCHAR值。

获取您的代码并使用SQLCMD:

Black JL: sqlcmd -d stores - <<!
        > CREATE TABLE tmptable (txt varchar(240));
        > INSERT INTO tmptable (txt) VALUES ('123   ');
        > SELECT txt, txt || '***', LENGTH(txt) FROM tmptable;
        > !
123   |123   ***|3
Black JL:

'Black JL:'是机器'黑'上的Unix提示符;正如你所看到的,我得到了尾随空白(但我在大约20年前写过SQLCMD,现在,部分原因是因为DB-Access,或者更确切地说是它的前身ISQL,并没有为我的目的做足够仔细的事情)。

答案 1 :(得分:0)

对于那些不想猜测“正确类型”是什么的人,我通过指定“lvarchar”类型让我的esql程序工作。 (至少有一个版本的esql / c指南暗示“varchar”应该可以工作,但它不适合我)