あなたが書いたコードはあまり意味がありません。機能しないフェッチが多すぎる (1 つの変数に 2 つの列?)。
以下に例を示します:テスト テーブル:
SQL> create table test (email varchar2(30));
Table created.
SQL> insert into test
2 select '[email protected]' from dual union all
3 select '[email protected]' from dual union all
4 select '[email protected]' from dual union all
5 select '[email protected]' from dual;
4 rows created.
そこからドメイン部分を分割し (次の SELECT の 2 列目)、電子メール アドレスを新しいドメインに更新する方法 (3 列目):
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
------------------------- --------------- -------------------------
[email protected] hotmail.com [email protected]_domain.com
[email protected] net.hr [email protected]_domain.com
[email protected] gmail.com [email protected]_domain.com
[email protected] gmail.com [email protected]_domain.com
SQL>
Gmail の電子メール アドレスだけを新しいドメインに更新しましょう:
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
-------------------------
[email protected]
[email protected]
[email protected]_domain.com
[email protected]_domain.com
SQL>
プロシージャに変換したい場合は、問題ありません:
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
-------------------------
[email protected]
[email protected]
[email protected]_domain_2.com
[email protected]_domain_2.com
SQL>
どうしてもカーソルを使用したい場合 (なぜそうしたいのかわかりません。おそらく最も非効率的なオプションです)、ここに行きます:
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
-------------------------
[email protected]
[email protected]
[email protected]_domain_3.com
[email protected]_domain_3.com
SQL>
カーソル FOR ループは、試行よりも保守が簡単です (カーソルとカーソル変数の作成、カーソルのオープン、カーソルからのフェッチ、ループの終了の注意、カーソルのクローズ)。
しかし、それなしでは生きていけないなら、ここに行きましょう:
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
-------------------------
[email protected]
[email protected]
[email protected]_domain_4.com
[email protected]_domain_4.com
SQL>
私のおすすめ?可能であれば、純粋な SQL を使用してください。または最初の PL/SQL プロシージャ。この目的でカーソルを使用しないでください。