当我尝试将一些数据插入 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年的消息:
我更改了代码以使用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 中是否有任何设置可以使代码只有一个版本 两个司机?
版本信息:
首先,您真的确定要使用 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 驱动程序手册才能找到它。
可以通过以下步骤解决
卸载到“your_table.unl” SELECT * FROM your_table;
从 'your_table.unl' 加载插入到 your_table;
根据您的需求,使用命令行中的第一个脚本将数据导出为unl格式,并将其存储在用户目录中。如果需要,将文件传输到所需的服务器,然后运行第二个脚本将数据导入到目标表中。这样,您就不会遇到这个问题了。