[英]build oracle sql query dynamically from java application
如何從Java應用程序動態構建Oracle PL / SQL查詢? 將為用戶提供一堆列,這些列存在於數據庫的不同表中。 用戶可以選擇任何一組列,應用程序應僅使用包含選定列的表來構建完整的選擇查詢。 例如,讓我們考慮數據庫中有3個表。 用戶選擇col11,col22。 在這種情況下,應用程序應僅使用Tabl1和Tabl2構建查詢。 我該如何實現?
Tabl1
- col11
- col12
- col13
Tabl2
- fkTbl1
- col21
- col22
- col23
Tabl3
- col31
- col32
- col33
- fkTbl1
臨時報告是一個舊的收藏夾。 它經常在“報告要求”部分的結尾處顯示為單行:“用戶必須能夠定義和運行自己的報告”。 唯一的障礙是,即席報告本身就是一種應用程序 。
你說
“將為用戶提供一堆在數據庫中不同表中存在的列。”
如果預先選擇並嚴格控制“列數”(和表的分布),則可以避免我在下面討論的某些復雜性。 las,根據臨時報告的性質,用戶幾乎需要所有表中的所有列。
讓我們從您的示例開始。 用戶選擇了col11
和col22
,因此您需要生成以下查詢:
SELECT tabl1.col11
, tabl2.col22
FROM tabl1 JOIN tabl2
ON (TABL1.ID = TABL2.FKTABL1)
/
不太難。 您只需瀏覽數據字典視圖USER_CONSTRAINTS
和USER_CONS_COLUMNS
即可在USER_CONS_COLUMNS
中建立列-前提是您已定義了外鍵(請有外鍵!)。
如果我們添加第四個表,事情將變得更加復雜:
Tabl4
- col41
- col42
- col43
- fkTbl2
現在,當用戶選擇col11
和col42
您需要導航數據字典以建立Tabl2
充當連接Tabl4
和Tabl1
的中間表的Tabl1
(假定您不使用復合主鍵,因為大多數人沒有使用復合主鍵)。 但是假設用戶選擇col31
和col41
。 那是合法的組合嗎? 可以說是。 現在,您必須將Tabl4
到Tabl2
到Tabl1
到Tabl3
。 嗯...
如果用戶從兩個完全不相關的表Tabl1
和Tabl23
選擇列, Tabl23
怎么Tabl23
? 您是盲目生成CROSS JOIN
還是拋出異常? 這是你的選擇。
回到第一個查詢,它將返回兩個表中的所有行。 幾乎可以肯定,您的用戶將希望使用該選項來限制結果集。 因此,您需要為他們提供向WHERE
子句添加過濾器的功能。 這里的陷阱包括:
IN
列表而不是等於) LIKE
'%whatever%'
的風險?) 最后一點強調了即席報告固有的風險:如果用戶可以使用任何過濾器組合來自任何表的查詢,則他們可以組合查詢,這會消耗系統中的所有資源。 因此,最好應用配置文件來防止這種情況的發生。 同樣,正如我已經提到的,用戶有可能建立無意義的查詢。 請記住,您不需要在架構中使用太多表來生成太多要測試的排列。
最后,安全策略存在棘手的問題。 如果用戶被限制查看基於其部門或工作角色的數據子集,那么您將需要復制這些規則。 在這種情況下,通過行級安全性自動應用策略是真正的福音
所有這些都可能使您得出結論,最好的解決方案是促使用戶購買現成的產品。 盡管這種方法並非沒有自身的問題。
過去,我做這種事情的方式是簡單地使用StringBuilder即時構建SQL查詢,然后使用JDBC(未經准備的語句)執行它。 由於Oracle DB必須針對每個查詢重復所有查詢分析和優化工作,因此效率很低。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.