2011-09-12 47 views
6

考慮這個簡單的方法:如何在不使用不同的預處理語句的情況下處理NULL和常規值?

public ResultSet getByOwnerId(final Connection connection, final Integer id) throws SQLException { 
    PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?"); 
    statement.setObject(1, id); 
    return statement.executeQuery(); 
} 

範例方法應該從一些表,其中一列的值匹配,這應該是簡單的選擇應有盡有。 醜陋的細節是,傳遞NULL的ID將導致空結果,不管有多少行是在DB,因爲SQL NULL定義爲不euqaling點兒什麼,甚至不爲NULL。 選擇那些我知道行使用不同的WHERE子句的唯一方法:

SELECT * FROM MyTable WHERE MyColumn IS NULL 

不幸的是,只有這樣,才能使該方法正常工作在所有情況下似乎是有兩個完全不同的執行pathes,一個對於id參數爲空而一個用於常規值的情況。

這是非常醜陋的,當你有一個以上的列可以被清零可以得到非常混亂很快。如何使用相同的代碼路徑/語句處理NULL和正常值?

+0

我不使用JDBC,但在C#我一般設置這使得'='/'IS NULL'動態選擇?該參數(如果有的話)仍然通過準備好的語句進行綁定。 – 2011-09-12 17:56:53

+0

如果您使用的是SQL Server,那麼您可以執行SET SET_NULLS OFF,並且可以使用field = NULL。 – NullUserException

+1

考慮休眠或JPA。它將從JDBC樣板中拯救你。 – BalusC

回答

0

你可以使用這樣的查詢:

select * from MyTable where 
    case when ?1 is null then MyColumn is null else MyColumn = ?1 

重用相同的參數,所以我不知道是否語法,我建議將工作(1?)。

2

我沒有試過,但送零點到用預處理的方式是使用setNull()選項

PreparedStatement statement = connection.prepareStatement("SELECT * FROM MyTable WHERE MyColumn = ?"); 
    if (id == null) 
     statement.setNull(1, java.sql.Types.INTEGER); 
    else  
     statement.setObject(1, id); 
    return statement.executeQuery(); 

編輯:感謝您的答覆@Gabe和@Vache。它看起來並不像一個簡單的方法來做到這一點,而是採取更加靈活的方式來動態創建準備好的日誌。

像這樣的東西應該工作 -

​​
+0

在ANSI SQL中,即使MyColumn具有NULL值,MyColumn = NULL也不會成立。 – Gabe

+0

它會設置一個「SQL null」,但是「MyColumn = NULL」仍然不會返回任何結果。 'setNull'主要用於插入查詢。 – Vache

相關問題