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

发布于 2024-07-13 07:33:42 字数 3984 浏览 5 评论 0原文

我无法从 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 Dynamic Server Version 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 驱动程序
  • 不起作用 (修剪尾随空格c)与 JDBC-ODBC 桥

来源:

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

I cannot get trailing spaces from varchar column in Informix database.

I created test table, filled it with field with some trailing spaces,
but they are not returned by SELECT while it seems they are stored in db.

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

And I got fields:

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

Other databases I tested: Oracle and PostgreSQL return varchar fields
with trailing spaces. I tried RPAD() but with no success. Is there any way to get
trailing spaces?

Server: IBM Informix Dynamic Server Version 11.50.TC2DE

Client: tested with both ISA (no spaces in HTML page source) and ODBC driver 3.50.TC3DE

EDIT
Simple Python test program (tested with ActivePytnon 2.6 on Windows, you must change connection string in the last lines)

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')

And results:

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


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


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

Similar program in Jython using JDBC:

  • works (do not trim trailing spaces)
    with native JDBC driver
  • doesn't work
    (trim trailing spacec) with JDBC-ODBC
    bridge

Source:

# 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')

Results (for Informix only):

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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

躲猫猫 2024-07-20 07:33:42

在 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,没有按照我的目的足够仔细地做事)。

In ESQL/C, it is most certainly possible to get the trailing spaces from a VARCHAR column; my SQLCMD program (available from the IIUG Software Archive) does it. But you have to be extremely careful to use the correct type for the variables that hold the result. By default, the various char types are treated as CHAR rather than VARCHAR, and the libraries strip trailing blanks from CHAR values unless you direct otherwise (and blank pad to full length when you do direct otherwise).

Regarding ISA: I don't know how you established what it returns. I'm not altogether surprised that it loses the trailing blanks. Similar comments would apply to DB-Access.

Regarding ODBC: can you show the code, please, because although it is possible that there's a bug in the code (thank you for including the version information - it helps, and reassures me you are effectively up-to-date with your system), it is more likely that there is something up with the code you wrote to use it.

Regarding LENGTH(): it is defined to remove trailing blanks before calculating the length; it always treats its argument as if it was a CHAR value rather than as a VARCHAR value.

Taking your code and using 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:' is my Unix prompt on machine 'black'; as you can see, I got the trailing blanks OK (but I wrote SQLCMD about 20 years ago, now, in part because DB-Access, or rather its predecessor ISQL, didn't do things carefully enough for my purposes).

彩虹直至黑白 2024-07-20 07:33:42

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

For anyone that doesn't feel like guessing what the "correct type" is, I've gotten my esql program to work by specifying a "lvarchar" type. (at least one version of the esql/c guide implies that "varchar" should work, but it didn't for me)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文