Replacing Email Domains

前端 未结 1 1411
南旧
南旧 2021-01-23 10:34

I\'m trying to change the inputted domain name to a new domain name, for example, \"hotmail.com\" becomes \"outlook.com\". I believe I\'m on the right track, just my substring i

1条回答
  •  后悔当初
    2021-01-23 11:00

    Code you wrote doesn't make much sense; too much fetching which won't work (two columns into a single variable?).

    Here's an example: a test table:

    SQL> create table test (email varchar2(30));
    
    Table created.
    
    SQL> insert into test
      2    select 'lf@hotmail.com' from dual union all
      3    select 'bigfoot@net.hr' from dual union all
      4    select 'stack@gmail.com' from dual union all
      5    select 'overflow@gmail.com' from dual;
    
    4 rows created.
    

    How to split domain part from it (2nd column of the following SELECT) and update e-mail addresses to a new domain (3rd column):

    SQL> select email,
      2    substr(email, instr(email, '@') + 1) domain,
      3    replace(email,
      4            substr(email, instr(email, '@') + 1),
      5            'new_domain.com'
      6           ) result
      7  from test;
    
    EMAIL                     DOMAIN          RESULT
    ------------------------- --------------- -------------------------
    lf@hotmail.com            hotmail.com     lf@new_domain.com
    bigfoot@net.hr            net.hr          bigfoot@new_domain.com
    stack@gmail.com           gmail.com       stack@new_domain.com
    overflow@gmail.com        gmail.com       overflow@new_domain.com
    
    SQL>
    

    Let's update only Gmail e-mail addresses to a new domain:

    SQL> update test set
      2    email = replace(email,
      3                    substr(email, instr(email, '@') + 1),
      4                    'new_domain.com'
      5                   )
      6  where substr(email, instr(email, '@') + 1) = 'gmail.com';
    
    2 rows updated.
    
    SQL> select * From test;
    
    EMAIL
    -------------------------
    lf@hotmail.com
    bigfoot@net.hr
    stack@new_domain.com
    overflow@new_domain.com
    
    SQL>
    

    If you want to convert it to a procedure, no problem:

    SQL> rollback;
    
    Rollback complete.
    
    SQL> create or replace procedure p_change_domain
      2    (par_old_domain in varchar2,
      3     par_new_domain in varchar2)
      4  is
      5  begin
      6    update test set
      7      email = replace(email,
      8                      substr(email, instr(email, '@') + 1),
      9                      par_new_domain
     10                     )
     11    where substr(email, instr(email, '@') + 1) = par_old_domain;
     12  end;
     13  /
    
    Procedure created.
    
    SQL> exec p_change_domain('gmail.com', 'new_domain_2.com');
    
    PL/SQL procedure successfully completed.
    
    SQL> select * From test;
    
    EMAIL
    -------------------------
    lf@hotmail.com
    bigfoot@net.hr
    stack@new_domain_2.com
    overflow@new_domain_2.com
    
    SQL>
    

    If you desperately want to use cursors (I don't know why would you want to do that; it'll be probably the most inefficient option), here you go:

    SQL> rollback;
    
    Rollback complete.
    
    SQL> create or replace procedure p_change_domain
      2    (par_old_domain in varchar2,
      3     par_new_domain in varchar2)
      4  is
      5  begin
      6    for cur_r in (select email from test
      7                  where substr(email, instr(email, '@') + 1) = par_old_domain
      8                 )
      9    loop
     10      update test set
     11        email = replace(email,
     12                        substr(email, instr(email, '@') + 1),
     13                        par_new_domain
     14                       )
     15        where email = cur_r.email;
     16    end loop;
     17  end;
     18  /
    
    Procedure created.
    
    SQL> exec p_change_domain('gmail.com', 'new_domain_3.com');
    
    PL/SQL procedure successfully completed.
    
    SQL> select * From test;
    
    EMAIL
    -------------------------
    lf@hotmail.com
    bigfoot@net.hr
    stack@new_domain_3.com
    overflow@new_domain_3.com
    
    SQL>
    

    Cursor FOR loop is easier to maintain than your attempt (creating a cursor and a cursor variable, opening the cursor, fetching from it, taking care about exiting the loop, closing the cursor).

    But, if you can't live without it, here you go:

    SQL> rollback;
    
    Rollback complete.
    
    SQL> create or replace procedure p_change_domain
      2    (par_old_domain in varchar2,
      3     par_new_domain in varchar2)
      4  is
      5    cursor c1 is
      6      select email from test
      7      where substr(email, instr(email, '@') + 1) = par_old_domain;
      8    c1r c1%rowtype;
      9  begin
     10    open c1;
     11    loop
     12      fetch c1 into c1r;
     13      exit when c1%notfound;
     14
     15      update test set
     16        email = replace(email,
     17                        substr(email, instr(email, '@') + 1),
     18                        par_new_domain
     19                       )
     20        where email = c1r.email;
     21    end loop;
     22    close c1;
     23  end;
     24  /
    
    Procedure created.
    
    SQL> exec p_change_domain('gmail.com', 'new_domain_4.com');
    
    PL/SQL procedure successfully completed.
    
    SQL> select * From test;
    
    EMAIL
    -------------------------
    lf@hotmail.com
    bigfoot@net.hr
    stack@new_domain_4.com
    overflow@new_domain_4.com
    
    SQL>
    

    My suggestion? Use pure SQL, if possible. Or the first PL/SQL procedure. Don't use cursors for this purpose.

    0 讨论(0)
提交回复
热议问题