2015-09-16 247 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