2013-03-15 176 views
0

我遇到了在Oracle數據庫中執行一次批量更新的問題。Oracle循環插入

我願做羣衆插入到映射表,我們可以稱之爲地圖

有從中我獲得數據的其他兩個表的第一個表是賬號表從我可以使用此查詢選擇想要插入的帳戶:

select account_id 
from account 
where company_id in (
select company_id 
from company 
where company_name = 'string'); 

此查詢將根據我要插入的公司名稱選擇我的所有帳戶。

接下來,我有表我們可以稱之爲在這個表我有我插組,組有UID,以便我們GROUP_ID 1〜500

這裏的確切數字是多少,我需要做:我需要插入帳戶和組之間的表映射UID映射。有在需要做

insert into map (account_id, group_id) 
    values (number,number); 

但不幸的是,我不知道該怎麼做這種大規模的插入與包含有一個以上的結果,以及如何算循環選擇沒有特別的順序。

所以我的想法是做這樣的事情:

insert into map (account_id, group_id) values ((select account_id 
from account 
where company_id in (
select company_id 
from company 
where company_name = 'string')),loop from 1 to 500); 

隨着規則group_id可以與許多account_id s內插入,但一個account_id只能鏈接到一個組。

當然這個查詢不起作用,我只是想表達我想要做的事情。希望這是有道理的。

因爲我知道我到底想插什麼,所以我知道我有500 account_id s和50 group_id s。另外它們的順序意思是account_id 1到500和group_id 1到500,所以我認爲在這種情況下,應該相當容易以某種方式循環插入。

我希望我儘可能地讓自己清楚。

謝謝您的回答和建議!

+1

而不是真正漫長而令人困惑的解釋,你應該發佈樣本數據與預期的輸出。創建示例表格,將示例數據添加到表格,輸入所需的輸出等...您可以使用http://www.sqlfiddle.com/或在您的文章中輸入全部內容。使用Ctrl + K將代碼添加到您的帖子。 – Art 2013-03-15 18:19:14

+0

未來地圖表的要點是什麼?這是相當不清楚如何以及爲什麼你想加入組和帳戶。 – Sebas 2013-03-15 23:41:36

回答

1

這將插入帳戶ID和組ID的每個組合:

INSERT INTO map(account_id, group_id) 
SELECT a.id, g.id 
FROM account a, group g 
WHERE a.company_id IN (select company_id 
         from company 
         where company_name = 'string'); 

編輯:如果我理解你正確的評論,你想是這樣的:

INSERT INTO map(account_id, group_id) 
SELECT a.id, g.id 
FROM account a, group g 
WHERE a.company_id IN (SELECT company_id 
         FROM company 
         WHERE company_name = 'string') 
AND 1000 <= a.id AND a.id <= 1500 
AND g.id = a.id + 1000; 

將連接帳戶1000與組2000,組1001與組2001,依此類推。現在加入組是不必要的,但它會確保存在預期組ID的行(如果不存在,則跳過它)。

+0

謝謝你的回答!不幸的是,我可能是如此的準確,但我想只插入一些account_id和group_id的組合,我有成千上萬的兩個,但我想只插入一些映射表。所以我可以使用公司表中的選擇來識別/選擇所有的account_id,或者使用一些循環,因爲我知道我想插入的account_id是例如1000-1500,我也知道groups_id是2000-2500。現在它更有意義。 – Fil 2013-03-15 23:10:02

1

這樣的事情會起作用。它使用INSERT ... SELECT語法(請參閱示例here)從查詢中插入多行。

要循環,將結果與此查詢交叉連接,該查詢將爲您提供一個包含連續數字的500行的表。

select LEVEL as group_id from dual connect by LEVEL <= 500 

下面是最終答案。這是未經測試,所以你可能需要修正和調整,但是這是一般的方法:

insert into map (account_id, group_id) 
    select account_id, group_id 
    from account 
    where company_id in (select company_id 
         from company 
         where company_name = 'string') 
    cross join (select LEVEL as group_id 
       from dual 
       connect by LEVEL <= 500) 

加成 - OP問及如何包括組1000至1500(而不是1到500)的查詢會工作...

CONNECT BY LEVEL始終必須從1開始,因此您需要在內部查詢中使用CONNECT BY LEVEL <= 1500,並使用外部WHERE子句過濾掉1到999。這是一個例子。差異都在交叉連接查詢:

insert into map (account_id, group_id) 
    select account_id, group_id 
    from account 
    where company_id in (select company_id 
         from company 
         where company_name = 'string') 
    cross join (
    select group_id from (
     select LEVEL as group_id 
     from dual 
     connect by LEVEL <= 1500) 
    where group_id >= 1000) 

我不會在瞬間觸手可及有甲骨文所以這是未經測試就像我之前的回答。

另請注意:這樣的高達1500是沒有問題的,但在某些時候您會注意到放緩。我不知道它是一萬或一萬還是一百萬,但遲早你可能會碰壁。

+0

這看起來像我可以使用的東西!至少有什麼我可以在將來使用,我沒有如此強大的SQL,所以我正在解決從插入選擇與生成AWK單插入的巨大列表:D實際上已經寫了它的幾個殼生成器:D但我一直覺得它不是最好的解決方案。 – Fil 2013-03-15 23:17:27

+0

如果group_id不是由1開始,而是例如1000並結束於1500,那麼對於級別解決方案只有一個額外問題,如何應用此解決方案?對不起,沒有使用確切的數字,我試圖讓它更理論更多的可能的解決方案。 – Fil 2013-03-15 23:45:25

+0

@Fil - 對不起,今天剛剛看到你的「1000到1500」的問題,因爲我有一個長期未過期的週末離線:)我補充說,作爲我原來的答案編輯。 HTH。 – 2013-03-18 17:16:38

0

回答你的問題:

INSERT INTO map(account_id, group_id) 
SELECT a.id, g.id 
    FROM account a 
INNER JOIN company c 
    ON a.company_id = c.company_id 
    AND c.company_name = 'string' 
CROSS JOIN group g 

我的忌諱,退出控制SQL!您不必使用IN