2

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

我创建了测试表,用一些尾随空格填充了它,但是它们没有被 SELECT 返回,而它们似乎存储在数据库中。

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 动态服务器版本 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]

Jython 中使用 JDBC 的类似程序:

  • 与本机 JDBC 驱动程序一起工作(不修剪尾随空格)
  • 对 JDBC-ODBC 桥不起作用(修剪尾随空格c)

资源:

# 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]
4

2 回答 2

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

于 2009-01-21T15:42:26.517 回答
0

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

于 2009-01-28T22:02:58.607 回答