如何循环多个条件

时间:2019-11-26 11:34:18

标签: oracle plsql

我正在尝试创建一个查询,该查询需要循环两个条件(V_prj_id和V_email)。 目前,我已经创建了仅针对V_prj_id循环的查询。但是我也想为每个项目循环V_email。 由于我是oracle sql的新手。请对此提供建议。

查询:

 SET SERVEROUTPUT ON
Declare
 v_sql varchar2(500);
 v_sql2 varchar(30);
V_ACTION varchar(30) := 'ADD';
v_event  varchar2(500) := 'EVENT';
 v_email varchar2(200) := 'ABC@yahoo.com,xyz@yahoo.com,123@yahoo.com';
v_prj_id varchar2(4000):='PRJ1,PRJ2,PRJ3,PRJ4';


 BEGIN

Dbms_Output.Put_Line('v_prj_id='||v_prj_id);
--
FOR i IN (SELECT trim(regexp_substr(v_prj_id, '[^,]+', 1, LEVEL)) l
        FROM dual 
        CONNECT BY LEVEL <= regexp_count(v_prj_id, ',') + 1 
       ) LOOP
  --
  Dbms_Output.Put_Line('---------------------');
  --
  --

  IF V_ACTION = 'ADD'

  THEN

        v_sql := 'UPDATE ' || i.l|| '.Recipient set email = email ||'';''||:1 '  ;

  ELSE --IF V_ACTION = 'REMOVE'THEN


        v_sql := 'UPDATE ' || i.l|| '.Recipient set email = lower (replace (email, '';''||:1 )) '  ;



  END IF;

  --
  Dbms_Output.Put_Line('v_sql='||v_sql);
  --
  begin
    EXECUTE IMMEDIATE v_sql USING v_email;
    DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT||' rows are updated.');
  Exception
    when others then
         Dbms_Output.Put_Line('sqlerrm='||sqlerrm);
  End;
  --
  END LOOP;

END;

2 个答案:

答案 0 :(得分:1)

使用集合来保存数组,而不是尝试解析定界的字符串:

并且您也应该停止在表中使用定界字符串。代替以;分隔字符串的形式保存电子邮件,您应该为收件人的电子邮件创建一个单独的表并添加或删除行,而不是尝试添加或删除子字符串。

Declare
  v_sql    varchar2(500);
  v_sql2   varchar(30);
  V_ACTION varchar(30) := 'ADD';
  v_email  SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST( 'ABC@yahoo.com', 'xyz@yahoo.com', '123@yahoo.com' );
  v_prj_id SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST( 'PRJ1', 'PRJ2', 'PRJ3', 'PRJ4' );
BEGIN
  FOR i IN 1 .. v_email.COUNT LOOP
    FOR j IN 1 .. v_prj_id.COUNT LOOP
      IF V_ACTION = 'ADD' THEN
        v_sql := 'UPDATE ' || v_prj_id(j) || '.Recipient set email = TRIM( '';'' FROM email ||'';''||? )';
      ELSE
        v_sql := 'UPDATE ' || v_prj_id(j) || '.Recipient set email = TRIM( '';'' FROM lower (replace ('';''||email||'';'', '';''||?||'';'', '';'' ) ) )';
      END IF;

      Dbms_Output.Put_Line('v_sql='||v_sql || ' using ' || v_email(i));

      begin
        --EXECUTE IMMEDIATE v_sql USING v_email(i);
        --DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT||' rows are updated.');
        NULL;
      Exception
        when others then
          Dbms_Output.Put_Line('sqlerrm='||sqlerrm);
      End;
    END LOOP;
  END LOOP;
END;
/

输出:

v_sql=UPDATE PRJ1.Recipient set email = TRIM( ';' FROM email ||';'||? ) using ABC@yahoo.com
v_sql=UPDATE PRJ2.Recipient set email = TRIM( ';' FROM email ||';'||? ) using ABC@yahoo.com
v_sql=UPDATE PRJ3.Recipient set email = TRIM( ';' FROM email ||';'||? ) using ABC@yahoo.com
v_sql=UPDATE PRJ4.Recipient set email = TRIM( ';' FROM email ||';'||? ) using ABC@yahoo.com
v_sql=UPDATE PRJ1.Recipient set email = TRIM( ';' FROM email ||';'||? ) using xyz@yahoo.com
v_sql=UPDATE PRJ2.Recipient set email = TRIM( ';' FROM email ||';'||? ) using xyz@yahoo.com
v_sql=UPDATE PRJ3.Recipient set email = TRIM( ';' FROM email ||';'||? ) using xyz@yahoo.com
v_sql=UPDATE PRJ4.Recipient set email = TRIM( ';' FROM email ||';'||? ) using xyz@yahoo.com
v_sql=UPDATE PRJ1.Recipient set email = TRIM( ';' FROM email ||';'||? ) using 123@yahoo.com
v_sql=UPDATE PRJ2.Recipient set email = TRIM( ';' FROM email ||';'||? ) using 123@yahoo.com
v_sql=UPDATE PRJ3.Recipient set email = TRIM( ';' FROM email ||';'||? ) using 123@yahoo.com
v_sql=UPDATE PRJ4.Recipient set email = TRIM( ';' FROM email ||';'||? ) using 123@yahoo.com

db <>提琴here

答案 1 :(得分:0)

让SQL做组合而不是编写循环:

declare 
   v_action varchar2(8) := 'ADD'; 
   v_email  sys.odcivarchar2list := sys.odcivarchar2list( 'ABC@yahoo.com', 'xyz@yahoo.com', '123@yahoo.com' );
   v_prj_id sys.odcivarchar2list := sys.odcivarchar2list( 'PRJ1', 'PRJ2', 'PRJ3', 'PRJ4' );
   v_sql    varchar2(500);
   cursor proj_email_cursor is 
        ( select e.column_value email
               , p.column_value proj
            from table(v_email)  e
               , table(v_prj_id) p
        );
begin 
  for ep in proj_email_cursor
  loop
      if v_action = 'ADD' then
         v_sql := 'update ' || ep.proj || '.recipient set email = trim( '';'' from email ||'';''||? )';
      else
         v_sql := 'update ' || ep.proj  || '.recipient set email = trim( '';'' from lower (replace ('';''||email||'';'', '';''||?||'';'', '';'' ) ) )';
      end if;
      dbms_output.put_line (v_sql || ' using ' || ep.email);

      begin 
          --execute immediate vsql;
          dbms_output.put_line(ep.proj || ' rows updated=> ' || sql%rowcount);   
      exception 
          when others then
               dbms_output.put_line(ep.proj || ' error >> ' || sqlerrm );
      end ;                 
  end loop;
end;