2010-08-30 111 views
45

由於ResultSet包含從動態SQL返回的數據,如果有任何方法可以確定ResultSet是否包含特定的列名稱?例如,如果我運行rs.getString("Column_ABC");但Column_ABC並不存在,它將拋出異常。我如何測試ResultSet是否可以從名爲「Column_ABC」的列中獲取數據?如何確定列名是否存在於ResultSet中?

+0

可能重複?](http://stackoverflow.com/questions/462534/how-do-i-check-to-see-if-a-column-name-exists-in-a-cachedrowset) – bluish 2015-04-22 08:54:55

回答

67

使用ResultSetMetaData類。

public static boolean hasColumn(ResultSet rs, String columnName) throws SQLException { 
    ResultSetMetaData rsmd = rs.getMetaData(); 
    int columns = rsmd.getColumnCount(); 
    for (int x = 1; x <= columns; x++) { 
     if (columnName.equals(rsmd.getColumnName(x))) { 
      return true; 
     } 
    } 
    return false; 
} 

我不明白的是爲什麼這個功能會被需要。正在執行的查詢或存儲過程應該具有已知的結果。查詢的列應該是已知的。需要這樣的功能可能表明某處存在設計問題。

+0

在TOAD等工具中執行用戶查詢時,應用程序不知道查詢結構,並且必須使用「ResultSetMetaData」。但是,是的,搜索特定的列名是很奇怪的。 – gpeche 2010-08-31 07:05:21

+0

只是在你的例子中評論...你正在檢索所有列信息。對於用戶查詢,我希望這是標準的。這仍然不能搜索是否包含特定列。 – 2010-08-31 11:12:12

+8

這基本上是正確的,但'getColumnName'的參數從1開始不是0.您需要'for(int x = 1; x <= columns; x ++)' – 2012-05-03 14:33:37

-13

如果不是rs.getString( 「Column_ABC」)=沒有那麼 '在這裏你的代碼

+7

這是一個壞主意,這也是錯誤的。當列不存在時,它不會返回任何內容。它拋出一個SQLException,你必須捕捉和處理。你不應該使用這樣的簡單檢查來拋出異常。你應該總是尋找一種實際上會返回一個布爾值的方法 - 這實際上會執行一個適當的檢查。 – 2010-08-30 11:41:27

4

不知道這是否比Erick的答案更有效或更低效,但它更容易。

String str; 

try { 
    str = rs.getString(columnName); 
} catch (java.sql.SQLException e) { 
    str = null; 
} 
+1

毫無疑問,它更容易理解。但是,無論我沒有看到JDBC驅動程序返回「SQLServer」異常,ResultSet方法在列名無效或發生更通用的SQL錯誤時都會返回SQLException(這會導致知道發生了什麼:如果列名錯誤或發生實際錯誤)+ info @ [ResultSet Javadoc](http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#getObject-java.lang .String-) – 2014-08-12 13:50:42

+17

-1只能在特殊情況下使用異常,然後應該記錄日誌。簡單的出路往往會創建難以理解和維護的代碼。如果您在使用服務器端結果集並在進行此調用之前失去了與數據庫的連接,那麼即使該列存在,此方法也會引發異常。如果代碼使用此檢查(例如)來確定整個數據庫是否需要初始化,則此類方案可能會導致災難性後果。 – 2014-08-14 11:18:03

+0

非常感謝João。我的意思是SQLException。試圖選擇一個通用的。 – Zip184 2014-08-20 12:19:23

0
/** 
* returns default value if column is not present in resultset 
* 
* @param rs 
* @param columnLabel 
* @param defaultValue 
* @return 
*/ 
@SuppressWarnings("unchecked") 
private static <T> T getValueFromResultSet(final ResultSet rs, 
     String columnLabel, T defaultValue) { 
    try { 
     return (T) rs.getObject(columnLabel); 
    } catch (SQLException e) { 
     return defaultValue; 
    } 
} 

在Java版本> = 7你在ResultSet中#getObject方法路過類類型的選項

的[我如何檢查,看是否有列名CachedRowSet中存在
+0

這應該是正確的答案。這是一種安全的方式,可以根據行提供get對象類型,填充/映射對象,而不管它是否被填充,客戶端或底層業務邏輯應該知道應該期待什麼,並且安全地檢查它的數據。 – thekevshow 2016-09-30 05:45:42

+0

我不同意,埃裏克羅伯森解釋了爲什麼在上面的答案的評論。 – 2016-12-14 06:47:23

+0

儘管如此,它濫用異常處理背後的想法。 – Benedictus 2017-11-10 18:40:57

相關問題