Oracle SQL中似乎有1000個參數的限制。產生這樣的查詢....Oracle中的SQL參數限制
select * from orders where user_id IN(large list of ids over 1000)
我的解決辦法是建立一個臨時表,插入用戶ID成第一,而不是發出通過JDBC的查詢都有一個參數列表巨頭時,我就遇到了這個在IN。
有誰知道更簡單的解決方法嗎?由於我們使用Hibernate,我想知道它是否能夠自動地透明地執行類似的解決方法。
Oracle SQL中似乎有1000個參數的限制。產生這樣的查詢....Oracle中的SQL參數限制
select * from orders where user_id IN(large list of ids over 1000)
我的解決辦法是建立一個臨時表,插入用戶ID成第一,而不是發出通過JDBC的查詢都有一個參數列表巨頭時,我就遇到了這個在IN。
有誰知道更簡單的解決方法嗎?由於我們使用Hibernate,我想知道它是否能夠自動地透明地執行類似的解決方法。
另一種方法是傳遞一個數組到數據庫,並IN子句中使用TABLE()
功能。這可能會比臨時表執行得更好。它肯定會比運行多個查詢更高效。但是如果你有大量會話在做這些事情,你需要監視PGA內存的使用情況。另外,我不確定將它連接到Hibernate是多麼容易。
注意:TABLE()
函數在SQL引擎中運行,所以它們需要我們聲明一個SQL類型。
create or replace type tags_nt as table of varchar2(10);
/
以下示例使用幾千個隨機標籤填充數組。然後它使用查詢的IN子句中的數組。
declare
search_tags tags_nt;
n pls_integer;
begin
select name
bulk collect into search_tags
from (select name
from temp_tags
order by dbms_random.value)
where rownum <= 2000;
select count(*)
into n
from big_table
where name in (select * from table (search_tags));
dbms_output.put_line('tags match '||n||' rows!');
end;
/
只要臨時表是一個全局臨時表(即只對會話可見),這是推薦的做事方式(並且我會爲任何超過一打的參數走這條路線,更不用說了一千)。
我想知道你在哪裏/如何構建1000個參數的列表。如果這是一個半永久性分組(例如,所有員工都位於特定位置),那麼該分組應該在數據庫中,並且在那裏完成加入。數據庫的設計和構建非常迅速地進行連接。比將一堆id返回中間層然後將它們發送回數據庫要快得多。
select * from orders
where user_id in
(select user_id from users where location = :loc)
有關「如果這些ID在您的數據庫中,請使用連接/關聯」的意見成立。但是,如果您的ID列表來自別處,例如SOLR結果,則可以通過發出多個查詢(每個查詢不超過1000個ID),然後在內存中合併查詢結果來解決臨時表需求。如果您將初始ID列表放入獨特集合(如哈希集合),則可以一次彈出1000個ID。
您可以添加額外的謂詞列表分割成塊1000:
select * from orders where user_id IN (<first batch of 1000>)
OR user_id IN (<second batch of 1000>)
OR user_id IN ...
您是如何在首位生成大量id的列表的?他們是來自桌面還是查詢? (我以某種方式懷疑用戶界面生成了許多參數...) – YogoZuno 2009-12-21 23:36:08
當ID列表來自其他來源(例如搜索引擎)時,通常會發生這種情況。即其在非整合後端之間進行關聯的方法。 – zzzeek 2009-12-21 23:41:27
通常,ID來自用戶在UI上執行批量操作。 – benstpierre 2009-12-22 16:32:56