user1332821
user1332821

Reputation: 83

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

Upvotes: 4

Views: 35674

Answers (2)

Jeffrey Kemp
Jeffrey Kemp

Reputation: 60262

  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.

Upvotes: 10

A.B.Cade
A.B.Cade

Reputation: 16905

As Jeffrey Kemp said this can be done in one update statemant:

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;

Upvotes: 2

Related Questions