6

「 JDK1.6のNationalCharacterSet Type Dataの新しいメソッド」を使用して、キリル文字を処理する標準のJDBCソリューションを取得しようとしていますが、実行がNVARCHARタイプの行に到達すると、たとえば次のようになります。

preparedSelect.setObject(3, "суббота", Types.NVARCHAR);

次に、この例外が発生します。

java.sql.SQLException: Invalid column type
    at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:131)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:197)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:261)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:269)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:490)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:7922)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:7502)
    at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:7975)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:222)

setNString()も使用しようとしましたが、さらに奇妙な例外が発生します。

java.lang.AbstractMethodError: oracle.jdbc.driver.OraclePreparedStatementWrapper.setNString(ILjava/lang/String;)V

java -Doracle.jdbc.defaultNChar = true myApplicationを通常のTypes.VARCHARで使用すると、ロシア語の単語が正しく保存されます。ただし、-Doracle.jdbc.defaultNChar = trueを使用することはできません。これは、レガシーアプリケーションで作業しているため、実行中の本番環境を制御できず、コンポーネントを書き込んでいるだけです。さらに、この「Readme for NChar How-to」には、「この変換はパフォーマンスに大きな影響を与える」と記載されています。したがって、テーブルの1%未満しかこの変換を必要としない場合、デフォルトですべてをNCharに設定するのは、賢明な選択ではありません。

oracleシンドライバーを使用しており、クラスパスにojdbc6.jarとorai18n.jarがあります。

標準のJDBCソリューションを探しています。「oracle」が付いたメソッドや定数は使用できません。OraclePreparedStatementは私にとってオプションではありません。

MSSQL ServerでTypes.NVARCHARを使用してみましたが、正常に動作します。

4

2 に答える 2

2

私は解決策を見つけました!

私はojdbc11.2.0.1を使用していました。11.2.0.2に切り替えると、setNString()正常に動作するようになりました。しかし、と一緒java.sql.SQLException: Invalid column typeに使用setObject()しても同じようになりますType.NVARCHAR。オラクルの恥...

とにかく、解決策:ojdbc11.2.0.2に切り替えます

于 2011-06-08T16:00:01.927 に答える
0

私はそれを少し前に次の呪文でうまく動かすことができました。これらのメソッドは、より大きなクラスからの抜粋です。

import com.mchange.v2.c3p0.C3P0ProxyStatement;
import oracle.jdbc.OraclePreparedStatement;

    static {
        try {
            SET_FORM_OF_USE_METHOD = OraclePreparedStatement.class.getDeclaredMethod("setFormOfUse", new Class[] { Integer.TYPE, Short.TYPE });
        } catch (NoSuchMethodException ex) {
            LOG.fatal("Can't find the setFormOfUse method", ex);
            throw new ExceptionInInitializerError(ex);
        }
    }


    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws SQLException {
        if (st instanceof OraclePreparedStatement) {
            ((OraclePreparedStatement)st).setFormOfUse(index, OraclePreparedStatement.FORM_NCHAR); 
        } else if (st instanceof C3P0ProxyStatement) {
            try {
                C3P0ProxyStatement c3p0St = (C3P0ProxyStatement) st;
                c3p0St.rawStatementOperation(SET_FORM_OF_USE_METHOD, C3P0ProxyStatement.RAW_STATEMENT, new Object[]{index, OraclePreparedStatement.FORM_NCHAR});
            } catch (IllegalAccessException ex) {
                throw new UnexpectedException("Error calling setFormOfUse through C3P0", ex);
            } catch (IllegalArgumentException ex) {
                throw new UnexpectedException("Error calling setFormOfUse through C3P0", ex);
            } catch (InvocationTargetException ex) {
                throw new UnexpectedException("Error calling setFormOfUse through C3P0", ex);
            }
        } else {
            throw new IllegalArgumentException("Unkown PreparedStatement implementation: " + st.getClass() + ". Maybe an unknown connection pool is hiding the OraclePreparedStatement?");
        }

        st.setString(index, (String) value);
    }

nullSafeSetメソッドは、OraclePreparedStatementインスタンスで直接機能するように、またはC3P0接続プールがある場合はC3P0ProxyStatementで機能するように構成されています。プールが異なる場合は、他のオプションを使用する必要があります。

このメソッドは、Oracle10.2.0.4のojdbc14.jarで機能しました。

于 2010-11-16T19:11:46.220 に答える