2012-09-07 47 views
6

假設我想要一個JasperReport,如果用戶願意,它可以讓用戶過濾日期。在SQL如下:。有條件的JasperReports Where子句

select * from foo where bar = $P{bar} and some_date > $P{some.date} 

現在,我不想被一些日期進行過濾,如果他們沒有通過的日期在我發現下面的雜牌人們使用:

select * from foo where bar = $P{bar} $P!{some.date.fragment} 

而且some.date.fragment參數定義與下面的默認:

($P{some.date} == null || $P{some.date}.equals("")) ? "" : "AND some_date >'" + new java.sql.Date($P{some.date}.getTime()).toString() + "'" 

這不是爲toString工作不輸出的日期,我SQL服務器可以理解的格式。我希望條件仍然使用jdbc驅動程序的準備語句並拋出參數,我只是希望準備好的語句依賴於參數是否爲null。這可以做到嗎?

+0

在我的情況下,第二個參數是一個字符串,where子句我用$ P {} stringValue的的一部分。 –

回答

6

在使用$P!{}表達式之前,JDBC驅動程序會爲您進行所有格式化。

但是,如果使用$P!{}表達式,則必須格式化自己。

像這樣的東西應該工作:

(
$P{some.date} == null 
? 
"" 
: 
"AND some_date >'" + (new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS")).format($P{some.date}) + "'" 
) 

根據您的數據類型,你必須定製dd.MM.yyyy HH:mm:ss.SSS

如果您不想使用$P!{}表達式,則可以使用下面的解決方案避免它。

我個人不喜歡這種方式。這也可能會導致一個糟糕的執行計劃。

如果不想使用$P!{},因爲您擔心sql注入。只要您的參數$P{some.date}包含像java.lang.Date這樣的安全數據類型,就沒有必要。


創建參數。讓我們把它${is_null_pram}並添加與PARAM類Integer默認表情:

($P{some.date} == null ? 1 : 0) 

現在你可以查詢:

SELECT 
    * 
FROM foo 
WHERE 
    bar = $P{bar} 
    AND 
     (
      some_date > $P{some.date} 
      OR 1 = $P{is_null_pram} 
     ) 
+0

那麼這些解決方案都不是我想要的理想解決方案。我希望null參數更改正在執行的sql,但我也希望jdbc驅動程序參數化輸入。我討厭搞清楚日期格式等等。然而,第二種選擇似乎更好,我用show plan/explain plan做了一些測試,並且數據庫處理OR時,如果存在1 = 1的真實條件,則忽略謂詞。 –

+0

僅供參考,任何人都可以看到。有'is_null_param'是一個整數,你可以比較另一個1。字符串比較沒有得到優化,以及一些數據庫。 –

+0

Jup。編輯完成。謝謝。 – edze

1

我想你可以使用的功能:

$X{EQUAL, <column_name>, <parameter_name>}

它會優化查詢,您可以在this幫助頁面中看到。

0

您可以使用此條件語句

select * 
    from foo 
    where bar = $P{bar} and some_date > $P{some.date} or $P{some.date} is null