2010-11-23 22 views
1

データベースからさまざまなプロパティにアクセスするためにプレーンなバニラJDBCコードを使用するアプリケーションがあります。これは、データベースの下には不可知論的です。しかし、それが使用する機能の一つは、(特に、列が、接続のメタデータ上のgetColumnsの結果にIS_AUTOINCREMENTの値にアクセスしてオートインクリメントされるかどうかを判断しようとしている)ドライバはJDBC4に準拠する必要がOracleドライバはJDBC4と本当に互換性があります

参照:http://download.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getColumns%28java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String%29

は事もJDBC 4準拠するように主張してojdbc6.jarに含まれているOracleのoracle.jdbc.OracleDriverを使用して、それがIS_AUTOINCREMENT列を返していないこと、であるが、JDBC 4仕様に追加しましたこれにより、未知の列に対してSQLExceptionが生成され、アプリケーションがOracle DBに対して使用不能になります。

次のようにOracleのドライバによって実行されたSQLクエリは次のとおりです。

SELECT NULL ASのTABLE_CAT、TABLE_SCHEM AS t.ownerは、table_name AS t.table_name、column_nameに、 DECODE(AS t.column_name 'LONG'、-1、 'DATE'、93、 'RAW'、-3、 'LONG RAW'、-4のいずれかになります。 、 'TIMESTAMP(6)'、93、 'TIMESTAMP(6)WITH TIME ZONE'、-101、 '012' 、 ' IMESTAMP(6)ローカルタイムゾーン '、-102、 'インターバル1年(2)〜月 '、-103、 'インターバル日(2)〜2(6) '、-104、 ' BINARY_FLOAT '、100 'BINARY_DOUBLE'、101、 'XMLTYPE'、2007、DATA_TYPE AS 1111) 、TYPE_NAME AS t.data_type、 DECODE(t.data_precision、ヌル、DECODE(t.data_type、 'CHAR'、 トン。 CHAR_LENGTH、
'VARCHAR'、t.char_length、
'VARCHAR2'、t.char_length、
'NVARCHAR2'、t.char_length、
'NCHAR'、t.char_length、
COLUMN_SIZE、 0 BUFFER_LENGTH AS、 DECODE(t.data_type、 '番号'、DECODE(t.data_precision、
ヌル、-127、AS'NUMBER'、0、t.data_length)、 t.data_precision) DECIMAL_DIGITS AS
t.data_scale)、
t.data_scale)、NUM_PREC_RADIX AS 10、 DECODE(t.nullable、 'N'、0、発言AS 1)AS NULL可能、 NULL、 t.data_default AS COLUMN_DEF 、 0 AS sql_data_type、 0 AS sql_datetime_sub、 t.data_length AS char_octet_length、ORDINAL_POSITION ASt.column_id、t.owner LIKE ALL_TAB_COLUMNS TからAS IS_NULLABLE DECODE(t.nullable、 'N'、 'NO'、 'YES'):1 ESCAPE '/' AND t.table_name LIKE :2 ESCAPE '/' AND t.column_name LIKE :TABLE_SCHEM BY 3 ESCAPE '/' ORDERは、 TABLE_NAME、ORDINAL_POSITION

はこれに任意のドライバ/代替/回避策はありますか?

+0

SQLExceptionに詳細が含まれていますか? –

+0

結果セットに列が存在しないことを示します。私は説明するために実行されたクエリを追加しています。 – Johnco

答えて

4

これはおそらく、IS_AUTOINCREMENT属性がOracleデータベースに関連していないためです。

もちろん、すべてのJDBCドライバが実際に仕様に準拠していれば、それは簡単ですが、これは一般的ではありません。 API仕様に記載されているように、Resultset.getString("IS_AUTOINCREMENT")は、列が自動インクリメントされているかどうかを判断できない場合、少なくとも空の文字列を返す必要があります。

あなたはこの動作をエミュレートしたい場合は、私はあなたが次のコードを使用することをお勧め:

 
String isAutoincrement = ""; 
try { 
    isAutoincrement = rset.getString("IS_AUTOINCREMENT"); 
} catch (SQLException sqle) { 
    log.warn("IS_AUTOINCREMENT attribute could not be retrieved", sqle); 
} 

データベースに依存しないアプリケーションを開発する場合、あなたはまた、他の属性のために、このチップを用いて検討すべきですたとえば「REMARKS」または「COLUMN_DEF」と入力します。より一般的には、あなたのコードは本当に守備的でなければなりません。なぜなら、JDBC実装は実際にベンダーごとに異なるからです。

+0

Oracleはオートインクリメント・カラムを使用していません。シーケンスを作成してトリガーで列に配線する必要があります。 –

+0

@トム、これがオラクルの "関連性"ではないと言った理由ですが、あなたが正しいです、私は私の答えでより具体的にすべきでした。 –

+0

そして、私はあなたの素晴らしい答えを広げていたということをより具体的に説明しておきました。 –

関連する問題