如何将字节数组插入Informix blob

时间:2014-03-26 13:07:30

标签: jdbc informix

如何将大字节数组插入Informix blob列?现在我有查询:

INSERT INTO TABLE (COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN_BLOB)
    VALUES(?, ?, ?, ?, ?)

引发了一个非常奇怪的例外:

org.sqlproc.engine.SqlProcessorException: SQL '  INSERT INTO TABLE (COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLOMN_BLOB   )   VALUES(?, ?, ?, ?, ?)'. org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLException: The specified table (into) is not in the database.
Caused by: java.sql.SQLException: The specified table (into) is not in the database.
    at com.informix.jdbc.IfxSqli.a(IfxSqli.java:3545)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3871)
    at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2661)
    at com.informix.jdbc.IfxSqli.receiveMessage(IfxSqli.java:2577)
    at com.informix.jdbc.IfxSqli.executeFastPath(IfxSqli.java:5981)
    at com.informix.jdbc.IfxSqli.executeFastPath(IfxSqli.java:5892)
    at com.informix.jdbc.IfxSmartBlob.IfxLoColInfo(IfxSmartBlob.java:306)
    at com.informix.jdbc.IfxSmBlob.i(IfxSmBlob.java:787)
    at com.informix.jdbc.IfxSmBlob.a(IfxSmBlob.java:520)
    at com.informix.jdbc.IfxResultSet.b(IfxResultSet.java:291)
    at com.informix.jdbc.IfxStatement.c(IfxStatement.java:1275)
    at com.informix.jdbc.IfxPreparedStatement.executeUpdate(IfxPreparedStatement.java:418)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.sqlproc.engine.spring.SpringQuery$9.doInPreparedStatement(SpringQuery.java:454)
    at org.sqlproc.engine.spring.SpringQuery$9.doInPreparedStatement(SpringQuery.java:448)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587)
    ... 44 more
Caused by: java.sql.SQLException: ISAM error: no record found.
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:412)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3876)
    ... 59 more

我正在使用sqlProcessor,它使用预准备语句将blob插入表中:

@Override
public void set(PreparedStatement st, int index, Object value) throws SQLException {
    byte[] bytes = (byte[]) value;
    st.setBytes(index, bytes);
}

DDL:

CREATE TABLE table1 (
  COLUMN1 BIGINT ,
  COLUMN2 VARCHAR(30) ,
  COLUMN3 INTEGER ,
  COLUMN4 INTEGER ,
  COLUMN_BLOB blob 
);

Informix服务器是在AIX 7.1上运行的Informix 12.10。

更新

好的,我解决了第一个问题。 sql以space开头,这对informix来说是个问题。但现在我有另一个例外:

Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL []; SQL state [IX000]; error code [-9810]; Smart-large-object error.; nested exception is java.sql.SQLException: Smart-large-object error.
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
    at org.sqlproc.engine.spring.SpringQuery.updateWithoutGenKeys(SpringQuery.java:448)
    at org.sqlproc.engine.spring.SpringQuery.update(SpringQuery.java:293)
    ... 42 more
Caused by: java.sql.SQLException: Smart-large-object error.
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:412)
    at com.informix.jdbc.IfxSqli.a(IfxSqli.java:3549)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3871)
    at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2661)
    at com.informix.jdbc.IfxSqli.receiveMessage(IfxSqli.java:2577)
    at com.informix.jdbc.IfxSqli.executeFastPath(IfxSqli.java:5981)
    at com.informix.jdbc.IfxSqli.executeFastPath(IfxSqli.java:5892)
    at com.informix.jdbc.IfxSmartBlob.IfxLoCreate(IfxSmartBlob.java:376)
    at com.informix.jdbc.IfxSmBlob.i(IfxSmBlob.java:790)
    at com.informix.jdbc.IfxSmBlob.a(IfxSmBlob.java:520)
    at com.informix.jdbc.IfxResultSet.b(IfxResultSet.java:291)
    at com.informix.jdbc.IfxStatement.c(IfxStatement.java:1275)
    at com.informix.jdbc.IfxPreparedStatement.executeUpdate(IfxPreparedStatement.java:418)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.sqlproc.engine.spring.SpringQuery$9.doInPreparedStatement(SpringQuery.java:454)
    at org.sqlproc.engine.spring.SpringQuery$9.doInPreparedStatement(SpringQuery.java:448)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587)
    ... 44 more
Caused by: java.sql.SQLException: Smart Large Objects: No sbspace number specified.
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:412)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3876)
    ... 59 more

2 个答案:

答案 0 :(得分:0)

我创建了类似的表和简单的Jython程序,测试插入BLOB列并从中进行选择。

作为测试数据,我使用带有史努比卡通的GIF文件: - )

#!/usr/bin/env jython
# -*- coding: utf8 -*-

import time

from java.sql import DriverManager
from java.lang import Class
from java.io import FileInputStream
from java.io import ByteArrayOutputStream

Class.forName("com.informix.jdbc.IfxDriver")

"""
create table _blob_test_so (
    id serial,
    txt varchar(30),
    column_blob blob
);
"""

def test_blob_insert(db):
    print('inserting gif picture into blob table...')
    blob = FileInputStream('snoopy_comics20121023.gif')
    insert_stmt = db.prepareStatement("INSERT INTO _blob_test_so (txt, column_blob) VALUES (?, ?)")
    insert_stmt.setString(1, 'test %s' % (time.strftime('%Y-%m-%d %H:%M:%S')))
    insert_stmt.setBinaryStream(2, blob)
    #insert_stmt.setBytes(2, [0, 1, 2, 3])
    rec_cnt = insert_stmt.executeUpdate()
    blob.close()
    print('records changed: %d' % (rec_cnt))

def test_blob_select(db):
    print('selecting data from blob table...')
    pstm = db.prepareStatement("SELECT id, txt, column_blob FROM _blob_test_so")
    rs = pstm.executeQuery()
    while (rs.next()):
        id = rs.getInt(1)
        txt = rs.getString(2)
        image_stream = rs.getBinaryStream(3)
        fout = ByteArrayOutputStream()
        while 1:
            b = image_stream.read()
            if b < 0:
                break
            fout.write(b)
        arr = fout.toByteArray()
        fname_out = 'test_%s.gif' % (id)
        print('%d:%s: fname: %s %d [b]' % (id, txt, fname_out, len(arr)))
        f = open(fname_out, 'wb')
        f.write(arr)
        f.close()

def test_version(db):
    try:
        dbmi = db.getMetaData();
        print('-' * 10)
        print("JDBC driver version is '%s'; major: %s; minor: %s" % (dbmi.getDriverVersion(), dbmi.getDriverMajorVersion(), dbmi.getDriverMinorVersion()));
        c = db.createStatement()
        rs = c.executeQuery("SELECT FIRST 1 DBINFO('version','full') FROM systables")
        while (rs.next()):
            print("Server version: '%s'" % (rs.getString(1)))
    except:
        print("there were errors!")
        s = traceback.format_exc()
        sys.stderr.write("%s\n" % (s))


db = DriverManager.getConnection('jdbc:informix-sqli://test-informix/test:informixserver=ol_testifx;DB_LOCALE=pl_PL.CP1250;CLIENT_LOCALE=pl_PL.CP1250;charSet=CP1250', 'informix', 'informix')
test_version(db)
test_blob_insert(db)
test_blob_select(db)

我在java1.7.0_51上使用Jython 2.5.3。在我的环境中它运作良好。它报告我使用:

JDBC driver version is '4.10.JC2DE'; major: 4; minor: 10
Server version: 'IBM Informix Dynamic Server Version 11.50.FC4    '

它会创建与test_*.gif相同的snoopy_comics20121023.gif个文件。

所以我的结论是你的环境存在问题。我怀疑是JDBC驱动程序。

答案 1 :(得分:0)

根据我的经验,当没有定义临时sb空间时会发生这种情况。

有关如何创建sb-space的示例如下:

onspaces -c -S sbddbs -p /infentw/sbdbs01.dat -o 0 -s 1000000
onbar -b -F

还必须添加到$ ONCONFIG:

SBSPACENAME     sbddbs       # Default smartblob space name

最后,您必须重新启动informix服务器。

onmode -ky; oninit -v