6

ランダムに生成される問題があります (1,000 分の 1 の呼び出しの間に 1 回)。エラーORA-01722: 無効な番号が、準備済みステートメントの Oracle データベースで sql update を実行しているときにランダムに生成されます。ケースの詳細は以下の通りです。

try {
        connection = getConnection();
        statement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            if (params[i] instanceof Date) {
                statement.setTimestamp(i + 1, new Timestamp(((Date) params[i]).getTime()));
            } else if (params[i] instanceof java.util.Date) {
                statement.setTimestamp(i + 1, new Timestamp(((java.util.Date) params[i]).getTime()));
            } else {
                statement.setObject(i + 1, params[i]);
            }
            paramsBuilder.append(": " + params[i]);
        }
        if (logger.isInfoEnabled()) {
            logger.info("Query String  [" + sql + "] [" + paramsBuilder + "]");
            logger.info("Query Parameters [" + paramsBuilder + "]");
        }
        result = statement.executeUpdate();
        if (logger.isInfoEnabled()) {
            logger.info(result + " rows affected");
        }
    } catch (SQLException e) {
        if (logger.isInfoEnabled()) {
            String message = "Failed to execute SQL statment [" + sql + "] with parameters [" + paramsBuilder + "]";
            logger.error(message, e);
        }
        throw new DAOException(e);
    }

ログの値は次のようになります。

Failed to execute SQL statment [update CUSTOMER_CASE set no_of_ptp=?, no_of_unreached=?,collector_name=? , last_case_status_history_id=?, current_handler=?, handling_start_time=?,due_total_open_amount=?, payment_due_invoice_id =?  where id=?] with parameters [: 0: 0: auto: 5470508: null: null: 0.0: 23410984: 2476739] java.sql.SQLException: ORA-01722: invalid number

DB でクエリ パラメータをトレースすると、すべてのパラメータが JDBC ドライバを介して正しく転送されます。ただし、パラメータ23410984は値に置き換えられます"<C4>^X* U"(この値には、char 'u' の前にキャリッジ リターンが含まれていることに注意してください!)。どうしてか分かりません

4

5 に答える 5

5

主な理由は約java.sql.SQLException: ORA-01722: invalid numberです。
フィールドlast_case_status_history_idタイプは数値である可能性がありますが、パラメーターはnullです

于 2012-05-17T14:11:45.190 に答える
3

同様の問題がありました。Hibernate ベースの Java コードは、aspectJ を使用して、すべての保存操作のユーザー情報と「変更の理由」を入力する準備済みステートメントを発行しました。

3 つの別々のデータベース環境 (Oracle 10G) では問題なく動作しましたが、実稼働データベースでは ORA-01722 エラーで失敗することがありました。これは、データベース サーバーの CPU 負荷が 100% に近い場合にのみ発生します。

別のフォーラムで、Long オブジェクトを渡すのではなく、長いプリミティブに対して明示的にボックス化解除を行うという提案を見つけました。高負荷でこのボックス化解除を行うと、jdbc ドライバーまたはデータベース自体に問題があるようです (かなりクレイジーに聞こえますが)。1.4 および 1.6 バージョンなど、さまざまな jdbc ドライバーがテストされました。

時々失敗したコードは次のとおりです。

private void execute(final Long userId, final String rfc) {
    Object[] args = new Object[]{ userId, rfc };
    getJdbcTemplate().update("call schema.package.setUserAndRFC(?,?)", args);
}

ここで、コードを変更して、次のように明示的な PreparedStatement を作成しました。

private void execute(final Long userId, final String rfc) {
    getJdbcTemplate().update(prepareStatement(userId.longValue(), rfc));
}

private PreparedStatementCreator prepareStatement(final long userId, final String rfc) {
    return new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
            PreparedStatement statement = con.prepareStatement("call schema.package.setUserAndRFC(?,?) ");
            statement.setLong(1, userId);
            statement.setString(2, rfc);
            return statement;
        }
    };
}

この問題は、同じソフトウェアとデータベースの高負荷で環境が同じままであったにもかかわらず、それ以来発生していません。

同僚から、DBA の 1 人がロギングで、準備されたステートメントがデータベースによって受け入れられたことを確認できたが、CPU が割り当てられていなかったと聞いたことがあります。(このような高負荷ではすべての CPU がビジーになるため、理にかなっています。)単に間違ったエラーがスローされたり、何らかの「データベースの過負荷」エラーがスローされたりする可能性があります。とにかく、そのようなエラーを作成しないことをお勧めします。

主にデータベースの負荷だと思いますが、CPUの負荷が常に100%に達するのは賢明ではありません。

于 2012-09-06T08:57:08.183 に答える
2

私はこれを試しました:

SELECT DUMP(23410984, 17)
FROM   dual;

そしてこれを手に入れました:

Typ=2 Len=5: c4,^X,*,^J,U

これは実質的にあなたが得たものと同じです。タイプ2はNUMBERデータ型です。

Oracleのドキュメントには、DUMP()関数の2番目のパラメータが記載されています。

17は、コンパイラの文字セット(通常はASCIIまたはEBCDIC)で印刷可能な文字として解釈できる場合にのみ、文字として印刷された各バイトを返します。一部のASCII制御文字は、^Xの形式でも出力される場合があります。それ以外の場合、文字は16進表記で印刷されます。すべてのNLSパラメータは無視されます。

そのため、値がNUMBERの内部バイト形式ではなく、文字列として転送される場合があるようです。

于 2012-05-17T14:14:21.277 に答える
0

java.sql.SQLException: ORA-01722: invalid number.

数値が期待される列の上にUDFを使用していましたが、数値ではない別の値を取得していました。そのため、操作は無効な番号の例外をスローして失敗します。

于 2016-10-07T05:27:40.547 に答える