【问题标题】:PL/SQL Cursor for loopPL/SQL 游标循环
【发布时间】:2012-04-28 07:26:59
【问题描述】:

我相信我需要一个用于循环的游标来遍历表 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

【问题讨论】:

    标签: oracle for-loop plsql database-cursor


    【解决方案1】:
    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 语句中完成所有操作。

    【讨论】:

    • 是的表有 newstreetnumber 和 newstreetname
    【解决方案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;
    

    【讨论】:

    • +1 就是这样。虽然我会将“instr(street1,'Cnr',1) >= 1”重写为“street1 like '%Cnr%'”
    猜你喜欢
    • 2012-03-27
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2021-07-30
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多