4

我相信我需要一个用于循环的游标来遍历表 test_data 中的 street1 列。我有一个程序需要测试表中的每一行。

这是我到目前为止所拥有的:

cursor c1 is
street1
from test_data

Begin
    If Instr(street1, ‘Cnr’, 1) >= 1;
    Then
        Newstreetname := Substr(street1, Instr(street1, ‘Cnr’, 1)+3);
    Else if
        Instr(street1, ‘PO Box’, 1) >= 1;
    Then
        Newstreetname:= Substr(street1, Instr(street1, ‘PO Box’, 1));
    Else if
        REGEXP_ Instr (street1, [\d], 1) = 0; 
    Then
        Newstreetname:= street1;
    Else if
        REGEXP_ Instr (street1, [\d], 1) >= 1;
    Then
        Newstreetnumber:= regexp_substr(street1, '\d+(\s|\/)(\d+)?-?(\d+)?(\w {1})?'); 
        Newstreetname:= regexp_substr(street1, '(\w+\s\w+)$'); 
End
4

2 回答 2

10
  1. 您需要在游标定义中使用 SELECT 和分号

  2. 您可以在光标上添加 FOR LOOP

    例如:

     DECLARE
       cursor c1 is
         SELECT street1
         from test_data;
       r1 c1%ROWTYPE;
     BEGIN
       FOR r1 IN c1 LOOP
          ... do your stuff with r1.street1
       END LOOP;
     END;
    

    或者,您可以完全避免显式游标定义,例如:

    FOR r1 IN (SELECT street1 FROM test_data) LOOP
      ... do your stuff with r1.street1
    END LOOP;
    
  3. 您的 IF 语句不能包含分号 - 例如:

     If
     Instr(r1.street1, 'Cnr', 1) >= 1
     Then
    
  4. [编辑] 所以你想更新你的表、列newstreetnumbernewstreetname- 在这种情况下你可以做这样的事情:

     DECLARE
       cursor c1 is
         SELECT street1
         from test_data
         FOR UPDATE;
       r1 c1%ROWTYPE;
     BEGIN
       FOR r1 IN c1 LOOP
          ... do your stuff with r1.street1
          UPDATE test_data
          SET newstreetnumber = ...
             ,newstreetname = ...
          WHERE CURRENT OF c1;
       END LOOP;
     END;
    

    但是请注意,这对于大容量不会很好,我更愿意在一个 UPDATE 语句中完成所有操作。

于 2012-04-17T03:56:38.847 回答
2

正如 Jeffrey Kemp 所说,这可以在一个更新声明中完成:

UPDATE test_data
   SET newstreetname = CASE WHEN Instr(street1, ‘Cnr’, 1) >= 1 
                             THEN Substr(street1, Instr(street1, ‘Cnr’, 1)+3)
                            WHEN Instr(street1, ‘PO Box’, 1) >= 1 
                             THEN Substr(street1, Instr(street1, ‘PO Box’, 1))
                            WHEN REGEXP_Instr (street1, '[\d]', 1) = 0 
                             THEN street1
                            WHEN REGEXP_Instr (street1, '[\d]', 1) >= 1 
                             THEN regexp_substr(street1, '(\w+\s\w+)$')
                       END,
       newstreetnumber = CASE WHEN .....
                       END;
于 2012-04-17T07:43:32.140 回答