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

标签 jdbc odbc informix

当我尝试向 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+be+supplied+within+this%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 动态服务器版本 11.50.TC2DE
  • 客户:
  • ODBC 驱动程序 3.50.TC3DE
  • IBM Informix JDBC 驱动程序用于 IBM Informix Dynamic Server 3.50.JC3DE
  • 最佳答案

    首先,您确定要使用 Informix TEXT 类型吗?该类型使用起来很麻烦,部分原因是您面临的问题。它早于任何 SQL 标准中关于大对象的任何内容(TEXT 在 SQL-2003 中仍然没有——尽管近似等效的结构 CLOB 和 BLOB 是)。 BYTE 和 TEXT blobs 的功能从那时起就没有改变过 - 哦,假设是 1996 年,尽管我怀疑有可能选择更早的日期,比如 1991 年。

    特别是,您计划在 TEXT 列中存储多少数据?您的示例显示了字符串“插入”;也就是说,我想,比你真正使用的要小得多。您应该知道 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 'locator' 结构并且正在以正确的方式传送参数格式。看来 ODBC 驱动程序并没有让您沉迷于类似的恶作剧。

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

    关于jdbc - 使用 JDBC 和 ODBC 将 TEXT 列插入 Informix 数据库的一致方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/483284/

    相关文章:

    MySql - 当 URL 中提供密码时,MySql 服务器认为没有密码

    sql - JDBC 错误 : java. sql.SQLException:无法提交空查询

    java - jdbc性能

    sql-server - 失去与 SQL Server 2005 数据库的 ODBC 连接

    excel - 在 Mac 中使用 ODBC 连接从 Excel 查询 Hive 时出现 HortonWorks “Table or view not found”

    jsp - response.sendRedirect 不起作用

    linux teradata ODBC SQLConnect 错误

    sql - 使用连接更新 Informix 表

    c++ - 如何在 Informix CSDK 和 OIC++ 中使用事务

    c - 如何在 Linux 平台上编译和运行 ESQL/C 程序?