標籤:class 情況下 支援 pid pen 經驗 get 包括 sch
項目從Oracle移植到PostgreSQL(9.4版)後,這幾天又出現故障,經跟蹤定位,確定原因是調用PgDatabaseMetaData.getPrimaryKeys()介面返回了空集。
眾所周知,大多數情況下SQL語句對錶名、列名都是大小寫不敏感(據本人經驗,linux平台的MySql預設對錶名區分大小寫,可算是個例外)。對應的,各資料庫JDBC也理應對大小寫不敏感,但實際情況是:PostgreSQL的JDBC的部分介面只認全部小寫表名、列名,而對全大寫、大小寫混合的情況都不支援。
PostgreSQL在其資料字典裡存放的都是全小寫表名、列名,,但JDBC的介面在處理時卻沒有進行大小寫轉換。以下是參考PostgreSQL-JDBC的源碼而改造得來的查詢某表主鍵的SQL代碼:
select pg_attribute.attname as colname,pg_type.typname as typename,pg_constraint.conname as pk_namefrom pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid inner join pg_attribute on pg_attribute.attrelid = pg_class.oid and pg_attribute.attnum = pg_constraint.conkey[1]inner join pg_type on pg_type.oid = pg_attribute.atttypidwhere pg_class.relname = ‘table_name‘ and pg_constraint.contype=‘p‘;
當table_name為全小寫時,可以獲得正確結果,其它情況結果均為空白。
也許PostgreSQL方面因某種原因而刻意為之,但本人傾向於認為這是bug。畢竟,其它主流資料庫的JDBC都能正確應對這種情況。
經簡單測試,本項目涉及的介面包括:
//擷取表主鍵public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException;//擷取表外鍵public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException;//擷取列名public String getColumnName(int column);
受影響的介面應該還有不少,很可能也不止PgDatabaseMetaData一個類;另外猜測,模式名、使用者名稱、資料庫名等可能也在影響之列。
但因項目時間緊迫沒有核實,大家在使用時留心這個問題,在應用程式中加入大小寫轉換的代碼。
PostgreSQL-JDBC疑似bug:部分介面參數的表名、列名必須全部小寫