使用 JDBC 和 ODBC 将 TEXT 列插入 Informix 数据库的一致方法

问题描述 投票:0回答:2

当我尝试将一些数据插入 Informix TEXT 列时遇到问题 通过 JDBC。在 ODBC 中,我可以像这样简单地运行 SQL:

INSERT INTO test_table (text_column) VALUES ('insert')

但这在 JDBC 中不起作用,我收到错误:

617: A blob data type must be supplied within this context.

我搜索了这样的问题,发现了2003年的消息:

http://groups.google.com/group/comp.databases.informix/browse_thread/thread/4dab38472e521269?ie=UTF-8&oe=utf-8&q=Informix+jdbc+%22A+blob+data+type+must+是+供应+以内+这个%22

我更改了代码以使用PreparedStatement。现在它可以与 JDBC 一起使用, 但在 ODBC 中,当我尝试使用PreparedStatement 时,出现错误:

Error: [Informix][Informix ODBC Driver][Informix]
Illegal attempt to convert Text/Byte blob type.
[SQLCode: -608], [SQLState: S1000]

测试表的创建方式为:

CREATE TABLE _text_test (id serial PRIMARY KEY, txt TEXT)

用于测试两个驱动程序的 Jython 代码:

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

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

def test_text(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
    Errors = []
    try:
        cursor = connection.cursor()
        cursor.execute("DELETE FROM _text_test")
        try:
            cursor.execute("INSERT INTO _text_test (txt) VALUES (?)", ['prepared', ])
            print "prepared insert ok"
        except:
            ex = sys.exc_info()
            s = 'Exception in prepared insert: %s: %s\n%s\n' % (ex[0], ex[1], traceback.format_exc())
            Errors.append(s)
        try:
            cursor.execute("INSERT INTO _text_test (txt) VALUES ('normal')")
            print "insert ok"
        except:
            ex = sys.exc_info()
            s = 'Exception in insert: %s: %s\n%s' % (ex[0], ex[1], traceback.format_exc())
            Errors.append(s)
        cursor.execute("SELECT id, txt FROM _text_test")
        print "\nData:"
        for row in cursor.fetchall():
            print '[%s]\t[%s]' % (row[0], row[1])
        if Errors:
            print "\nErrors:"
            print "\n".join(Errors)
    finally:
        cursor.close()
        connection.commit()
        connection.close()


#test_varchar(driver, db_url, usr, passwd)
test_text("sun.jdbc.odbc.JdbcOdbcDriver", 'jdbc:odbc:test_db', 'usr', 'passwd')
test_text("com.informix.jdbc.IfxDriver", 'jdbc:informix-sqli://169.0.1.225:9088/test_db:informixserver=ol_225;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250', 'usr', 'passwd')

JDBC 或 ODBC 中是否有任何设置可以使代码只有一个版本 两个司机?

版本信息:

  • 服务器:IBM Informix Dynamic Server 版本 11.50.TC2DE
  • 客户:
    • ODBC 驱动程序 3.50.TC3DE
    • 适用于 IBM Informix Dynamic Server 3.50.JC3DE 的 IBM Informix JDBC 驱动程序
jdbc odbc informix
2个回答
8
投票

首先,您真的确定要使用 Informix TEXT 类型吗?这种类型使用起来很麻烦,部分原因是您面临的问题。它早于任何 SQL 标准中关于大对象的任何内容(TEXT 仍然不在 SQL-2003 中 - 尽管大致相同的结构,CLOB 和 BLOB)。而且 BYTE 和 TEXT blob 的功能自 - 哦,比方说 1996 年以来就没有改变过,尽管我怀疑有选择更早日期的情况,比如 1991 年。

特别是,您计划在 TEXT 列中存储多少数据?您的示例显示字符串“insert”;也就是说,我认为比您实际使用的要小得多。您应该知道,BYTE 或 TEXT 列使用表中的 56 字节描述符以及单独的页(或页集)来存储实际数据。因此,对于这样的小字符串,这是对空间和带宽的浪费(因为 BYTE 或 TEXT 对象的数据将与行的其余部分分开在客户端和服务器之间传送)。如果您的大小不会超过 32 KB,那么您应该考虑使用 LVARCHAR 而不是 TEXT。如果您将使用高于此大小的数据大小,则 BYTE 或 TEXT 或 BLOB 或 CLOB 是明智的替代方案,但您应该考虑配置 blob 空间(对于 BYTE 或 TEXT)或智能 blob 空间(对于 BLOB 或 CLOB)。您可以并且正在使用 TEXT IN TABLE,而不是在 Blob 空间中;请注意,这样做会影响您的逻辑日志,而使用 blob 空间不会对它们产生太大影响。

我十年来一直在宣传的功能之一是能够将 SQL 语句中的字符串文字作为 TEXT 文字(或 BYTE 文字)传递。这部分是因为像你这样的人的经历。我还没有成功地将其优先于需要进行的其他更改。当然,您需要注意,SQL 语句的最大大小为 64 KB 文本,因此如果您不小心,可能会创建太大的 SQL 语句; SQL 中的占位符(问号)通常可以防止出现问题 - 增加 SQL 语句的大小是我一直在争取的另一个功能请求,但不太热心。

好的,假设您有充分的理由使用 TEXT……接下来做什么。我不清楚 Java(JDBC 驱动程序)在幕后做什么 - 除了太多 - 但可以肯定的是,它注意到需要 TEXT“定位器”结构并且正在以正确的方式传送参数格式。看来 ODBC 驱动程序不会让您沉迷于类似的恶作剧。

在我通常工作的 ESQL/C 中,代码必须以与其他所有内容不同的方式处理 BYTE 和 TEXT(并且必须再次以不同的方式处理 BLOB 和 CLOB)。但是您可以创建并填充定位器结构(locator.h 中的 loc_t 或 ifx_loc_t - 可能不在 ODBC 目录中;默认情况下位于 $INFORMIXDIR/incl/esql 中)并将其传递给 ESQL/C 代码作为SQL 语句中相关占位符的主变量。原则上,可能有一种可用于 ODBC 的并行方法。不过,您可能需要查看 Informix ODBC 驱动程序手册才能找到它。


0
投票

可以通过以下步骤解决

  1. 卸载到“your_table.unl” SELECT * FROM your_table;

  2. 从 'your_table.unl' 加载插入到 your_table;

根据您的需求,使用命令行中的第一个脚本将数据导出为unl格式,并将其存储在用户目录中。如果需要,将文件传输到所需的服务器,然后运行第二个脚本将数据导入到目标表中。这样,您就不会遇到这个问题了。

© www.soinside.com 2019 - 2024. All rights reserved.