2014-09-05 32 views
1

我們有很多數據庫中的數據,有時我們需要調用IN語句中有1000個以上項目的sql語句。我知道那些sql語句應該被重構,而IN子句不應該包含那麼多的項目,但有時候並不是那麼容易關注每個sql查詢。所以我有幾個問題。HSQLDB/Oracle - 在IN子句中有1000多個項目

  1. 有什麼可能解決這個問題?我發現幾個:
    • 重構SQL語句 - 並不總是那麼容易
    • 創建臨時表中的項目,以便IN子句將看起來像這樣... IN (SELECT id from temptable) - 可能是一個好主意
    • IN條款列入幾個IN條款喜歡... id IN (...) or id IN (...)
  2. Oracle db對IN子句有限制,但是我沒有發現我們用於單元測試的HSQLDB限制。是否可以通過HSQLDB中的某種配置或其他方式設置此限制?
  3. 關於IN子句的臨時表 - 如何使用HQL創建臨時表(我們在我們的應用程序中使用Hibernate 4.2)?可能嗎?
  4. 目前有些IN子句不會超過1000個項目,因爲我們在db中沒有那麼多的數據。但是在應用程序開始生產之後(它仍在開發過程中)將會有更多的數據,所以我們希望爲此做好準備。

你對這個問題有什麼經驗。你是如何解決它的?我們的環境

詳情:

  • 的Hibernate 4.2
  • HSQLDB 2.3.2
  • 的Oracle 11g
+0

另一個很好的例子,爲什麼使用不同的DBMS進行(單元)測試是一個壞主意 – 2015-05-27 12:46:28

回答

0

我認爲問題1已經已經回答了很多,但這裏有一個鏈接從Oracle Community到優雅的解決方案。

基本上,您創建了一個表類型和一個函數,可以將逗號分隔的字符串轉換爲表格。這允許您加入返回的表數據。

下面是我們如何實現一個逗號分隔的數字/ ID列表:

create or replace function in_number_list (in_list in varchar2) --send string 
return num_table          --return table of numbers 
as 
l_tab num_table := num_table();   -- blank table 
l_text varchar2(32767) := in_list || ','; -- passed string + extra ',' 
l_idx number;        -- a counter 

begin 
loop 
    l_idx := instr(l_text, ',');    -- find the first comma position 
    exit when nvl(l_idx,0) = 0;    -- if no more, break out of loop 
    l_tab.extend;        -- add a new row to table 
    l_tab(l_tab.last) := to_number(trim(substr(l_text,1,l_idx-1))); 
             -- add entry to table based on number 
             -- split from string 
    l_text := substr(l_text,l_idx+1);   -- reset the original string 
             -- trimming off what we've processed 
end loop; 
return l_tab;        -- send back table of numbers 
end; 
0

回覆問題2,HSQLDB不會在IN子句中的項目的數量加以限制,並沒有限制,可以徵收。