Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PL/SQL Cursor for loop

I believe I need a cursor for loop to go through the street1 column from table test_data. I have a program which needs to test each row from the table.

This is what I have so far:

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
like image 495
user1332821 Avatar asked Dec 16 '22 01:12

user1332821


1 Answers

  1. You need a SELECT and a semicolon in the cursor definition

  2. You can add a FOR LOOP over the cursor

    For example:

     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;
    

    You can, alternatively, avoid the explicit cursor definition entirely, e.g.:

    FOR r1 IN (SELECT street1 FROM test_data) LOOP
      ... do your stuff with r1.street1
    END LOOP;
    
  3. Your IF statements cannot include a semicolon - e.g.:

     If
     Instr(r1.street1, 'Cnr', 1) >= 1
     Then
    
  4. [edit] so you want to update your table, columns newstreetnumber and newstreetname - in which case you could do something like this:

     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;
    

    Note, however, that this will not perform well for large volumes, and I'd prefer to do it all in one UPDATE statement.

like image 197
Jeffrey Kemp Avatar answered Dec 29 '22 00:12

Jeffrey Kemp