4

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
0

2 Answers 2

10
  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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes table have newstreetnumber and newstreetname
2

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;

1 Comment

+1 This is the way. Although I'd rewrite the "instr(street1,'Cnr',1) >= 1" as "street1 like '%Cnr%'"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.