Как получить конечные пробелы из столбца varchar в Informix, используя ODBC - PullRequest
2 голосов
/ 21 января 2009

Я не могу получить конечные пробелы из столбца varchar в базе данных Informix.

Я создал тестовую таблицу, заполнил ее полем с пробелами, но они не возвращаются 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 версии 11.50.TC2DE

Клиент: протестирован с ISA (без пробелов в исходном тексте HTML) и драйвером ODBC 3.50.TC3DE

EDIT Простая тестовая программа Python (протестирована с ActivePytnon 2.6 в Windows, необходимо изменить строку подключения в последних строках)

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 мост

Источник:

# 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 голосов
/ 29 января 2009

Для тех, кому не хочется угадывать, что такое «правильный тип», я заставил мою программу esql работать, указав тип «lvarchar». (по крайней мере одна версия руководства esql / c подразумевает, что «varchar» должен работать, но это не для меня)

0 голосов
/ 21 января 2009

В ESQL / C, безусловно, возможно получить конечные пробелы из столбца VARCHAR; моя программа SQLCMD (доступна из IIUG Software Archive ) делает это. Но вы должны быть чрезвычайно осторожны, чтобы использовать правильный тип для переменных, которые содержат результат. По умолчанию различные типы символов обрабатываются как CHAR, а не как VARCHAR, и библиотеки убирают конечные пробелы из значений CHAR, если не указано иное (и пустая панель становится полной, если вы указываете иначе).

Относительно ISA: я не знаю, как вы установили, что он возвращает. Я не совсем удивлен, что он теряет конечные пробелы. Аналогичные комментарии будут применяться к DB-Access.

Относительно ODBC: не могли бы вы показать код, пожалуйста, потому что, хотя возможно, что в коде есть ошибка (спасибо, что включили информацию о версии - это помогает, и уверяет меня, что вы эффективно знакомы с вашей системы), более вероятно, что что-то не так с кодом, который вы написали для его использования.

Относительно ДЛИНЫ (): определено для удаления конечных пробелов перед вычислением длины; он всегда обрабатывает свой аргумент как значение 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-подсказка на машине 'black'; как вы можете видеть, я получил завершающие пробелы в порядке (но я написал SQLCMD около 20 лет назад, сейчас, отчасти потому, что DB-Access, или, скорее, его предшественник ISQL, не делал достаточно тщательно для моих целей).

...