2015-09-16 267 views
1

我想更新一個包含PHONE_NUMBER和COUNTRY列的表(T_NUMBERS)。 COUNTY COL爲空(全爲NULL),電話號碼不唯一,其格式爲:「420575757111」(以國家代碼開頭,不帶+或00)。國際呼叫代碼存儲在另一個表(INT_CODES)中,兩列:INT_CODE,COUNTRY。看起來像這樣:識別PL/SQL迭代中的電話號碼

COUNTRY  || INT_CODE 
------------------------- 
USA/CANADA || 1 
RUSSIA  || 7 
EGYPT  || 20 
GREECE  || 30 
BELGIUM  || 32 
FRANCE  || 33 
HUNGARY  || 36 
COLOMBIA || 57 
KENYA  || 254 
IRELAND  || 353 
GRENADA  || 1473 

等等。

我的理念是創建一個腳本,在工作方式如下:

  • 在第一輪第4位數字的電話號碼進行比較,以INT_CODE和更新INT_CODES的T_NUMBERS.COUNTRY領域。 COUNTRY它創立匹配,這樣的:

    INT_CODES.INT_CODE = SUBSTR(T_NUMBERS.PHONE_NUMBER,1,4) 
    
  • 之後第二輪比較第一3位數字,其中T_NUMBERS.COUNTRY仍然是NULL。

  • 在接下來的兩輪中,以相同的方式檢查2位和1位代碼,以填充所有國家字段,但不覆蓋已填充的字段。

我的問題是我不能運行這將至少執行第一步,因爲甲骨文似乎不支持在UPDATE語句中加入一個單一的腳本,你可以在這裏閱讀,例如:

Update statement with inner join on Oracle

,我試圖從答案的解決方案,但它不工作:

SQL錯誤:ORA-01427:單行子查詢返回不止一行

後,我試圖此(只有第一輪):

begin 
for t_rows in c_code 
loop 

    update (select TN.COUNTRY as C_OLD, IC.COUNTRY as C_NEW from T_NUMBERS TN 
    left join INT_CODES IC on IC.INT_CODE = substr(TN.PHONE_NUMBER,1,4) where 
    TN.COUNTRY IS NULL) T_TAB 

    set TAB.C_OLD = TAB.C_NEW; 
close c_code; 

end loop; 

錯誤消息: ORA-06512:在第8行 01779. 00000 - 「不能修改它映射到非一列鍵保存表「

所以我的主要問題是:什麼聲明我應該插入到循環? 我的問題:是否有任何其他解決方案來產生相同的結果(不創建更多的表格或修改現有的結構)?

在此先感謝。

回答

1

我會說它很難找到另一個SQL引擎更多功能豐富,然後甲骨文。 我建議你爲這樣的問題設置sqlfiddle

UPDATE t_numbers tn SET 
    tn.country = (
    SELECT ic.country 
    FROM int_codes ic 
    WHERE ic.int_code = substr(tn.phone_number, 1, 4) 
) 
WHERE tn.country IS NULL; 

如果你將它作爲pl/sql腳本運行,你可以用循環來包裝它,以避免複製/粘貼。

BEGIN 
    FOR i IN REVERSE 1..4 
    LOOP 
    UPDATE t_numbers tn SET 
     tn.country = (
     SELECT ic.country 
     FROM int_codes ic 
     WHERE ic.int_code = substr(tn.phone_number, 1, i) 
    ) 
    WHERE tn.country IS NULL; 
    END LOOP; 
END; 

此代碼依賴於一個事實,即在int_codes表列int_code是英國。

+0

在San的答案下看到我的反應。謝謝! – A117

+0

謝謝。我會更新答案以反映這個問題。 – Nagh

2

這裏需要什麼循環?你必須重新寫你的更新語句是這樣的:

UPDATE t_numbers tn 
    SET tn.country = (SELECT ic.country 
         FROM int_codes ic 
         WHERE ic.int_code = substr(tn.phone_number, 1, 4)) 
WHERE tn.country is null 
    AND EXISTS (SELECT 1 
       FROM int_codes ic 
       WHERE ic.int_code = substr(tn.phone_number, 1, 4)); 

然後重複同樣爲3,2,1,如下所示(3):

UPDATE t_numbers tn 
    SET tn.country = (SELECT ic.country 
         FROM int_codes ic 
         WHERE ic.int_code = substr(tn.phone_number, 1, 3)) 
WHERE tn.country is null 
    AND EXISTS (SELECT 1 
       FROM int_codes ic 
       WHERE ic.int_code = substr(tn.phone_number, 1, 3)); 

UPDATE:

您還可以通過循環4比1來實現任務

begin 
    for i in 1..4 loop 
     UPDATE t_numbers tn 
     SET tn.country = (SELECT ic.country 
          FROM int_codes ic 
          WHERE ic.int_code = substr(tn.phone_number, 1, (5-i))) 
    WHERE tn.country is null 
     AND EXISTS (SELECT 1 
        FROM int_codes ic 
        WHERE ic.int_code = substr(tn.phone_number, 1, (5-i))); 
    end loop; 
    END; 
+0

我試過了上述兩個解決方案,但錯誤消息仍然相同: – A117

+0

ORA-01427:單行子查詢返回多個行 – A117

+0

這意味着int_codes表中有多個條目用於給定int_code。根據它檢查並過濾數據。您可能需要在內部子查詢的條件中添加更多條件。 – San