[英]How to write sql query whose conditions are optional?
我必須編寫一個查詢,其中條件參數未知,因為它們是在jdbc中動態設置的。 這些條件應該是可選的。 我使用h2數據庫。 查詢是:
select e.event_id,a.attempt_id,a.preferred,a.duration,a.location
from event e,attempt a
where e.user_label=? and e.start_time=?
and e.end_time=? and e.duration_min=?
and e.duration_max=?
and e.event_id=a.event_id
但是如何使這些條件成為可選條件(除了使用OR之外,因為不知道參數)?
謝謝!
如果可以切換到命名參數 ,則可以將條件更改為檢查參數是否為null
,如下所示:
select e.event_id,a.attempt_id,a.preferred,a.duration,a.location
from event e,attempt a
where
(:ul is null OR e.user_label=:ul)
and (:st is null OR e.start_time=:st)
and (:et is null OR e.end_time=:et)
and (:dmin is null OR e.duration_min=:dmin)
and (:dmax is null OR e.duration_max=:dmax)
and e.event_id=a.event_id
如果無法切換到命名參數,則仍然可以使用相同的技巧,但是您需要為每個可選參數傳遞兩個參數:如果設置了第二個參數,則該對的第一個參數為1
如果第二個參數為0
則為0
一個被省略:
select e.event_id,a.attempt_id,a.preferred,a.duration,a.location
from event e,attempt a
where
(? = 1 OR e.user_label=?)
and (? = 1 OR e.start_time=?)
and (? = 1 OR e.end_time=?)
and (? = 1 OR e.duration_min=?)
and (? = 1 OR e.duration_max=?)
and e.event_id=a.event_id
您可能正在看的是動態SQL。 當所需的值不為null時,可以追加查詢中可以更改的部分:
String sqlQuery ="select e.event_id,a.attempt_id,a.preferred,a.duration,a.location from event e,attempt a where 1=1"
if (vUserLabel!=null){ //vUserLabel : The variable expected to contain the required value
sqlQuery = sqlQuery+"e.user_label=?";
}
稍后您可以執行:
int pos = 1;
...
if (vUserLabel!=null) {
stmt.setString(pos++, vUserLabel);
}
stmt.executeQuery(sqlQuery);
這樣,條件就可以動態地附加到查詢中,而無需重復努力,工作就完成了。
我自己的解決方案。 如果未提供命名參數,則刪除帶有[]的行。 因此,有時需要(1=1)
才能保持語法正常。
在這樣的示例中:label, :startt, :endt
是可選的,所有其他要求
select e.event_id,a.attempt_id,a.preferred,a.duration,a.location
from event e,attempt a
where (1=1) -- sometimes required
[and e.user_label=:label and e.start_time=:startt ]
[and e.end_time=:endt ]
and e.duration_min=:durationmin
and e.duration_max=:durationmax
and e.event_id=a.event_id
注意:我的重要問題是JDBC沒有命名參數。 我使用Spring JDBC NamedParameterJdbcTemplate,但有很大的依賴性。 許多臨時命名的參數解決方案都有錯誤,如果使用的參數大於1x (對我而言最重要的參數,請使用named代替positional)則構建錯誤的查詢,或者字符串替換對於特殊字符而言並不安全
好的,自問這個問題已經有一段時間了,但是我將寫出我的解決方案。
我發現,當查詢太大或太復雜時,在末尾附加另一個String並不容易,有時資源可以存儲在文件或db中,我所做的就是這樣。
我將查詢保存在.sql文件中,因此我在查詢中添加了一個標記。
存儲查詢的my.sql文件。
SELECT * FROM my_table
WHERE date_added BETWEEN :param1 and param2
$P{TEX_TO_REPLACE}
GROUP BY id
現在在我的代碼中
String qry = component.findQuery("my.sql");//READ THE FILE
String additionalQuery = " AND classification = 'GOB'";
if(condition1 == true) {
additionalQuery = " AND customer_id = 66";
}
qry = qry.replace("$P{TEX_TO_REPLACE}",additionalQuery);
現在我的查詢看起來像這樣。
SELECT * FROM my_table
WHERE date_added BETWEEN :param1 and param2
AND customer_id = 66
GROUP BY id
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.