for循环PL / SQL游标(PL/SQL Cursor for loop)

2019-07-29 00:52发布

我相信我需要一个游标循环都要经过从表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

Answer 1:

* 1。 你需要一个SELECT和游标定义一个分号

* 2。 您可以在游标FOR循环加

例如:

    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语句。



Answer 2:

正如杰弗里·肯普说,这可以在一个更新众所周知声明来完成:

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;


文章来源: PL/SQL Cursor for loop