oracleストレージプロセスでよく使われるテクニック(詳細)


私たちはpl/sqlのプログラミングをする時、一番多いのは記憶過程です。記憶過程の構造はとても簡単で、ここでは記憶過程の基本的な構造を学ぶ以外に、記憶過程を編纂する時に関連する実用的な知識を学びます。例えば、ラベルの処理、異常な処理、集合の選択などです。
1.格納プロセス構造
1.1最初の格納プロセス

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(20);  
begin  
 v_name := '   ';  
 p_para3 := v_name;  
 dbms_output.put_line('p_para3:'||p_para3);  
end; 
上は一番簡単な記憶プロセスです。一つの記憶プロセスは、大きくこのようないくつかの部分に分けられる。
作成文:create or replace procedure格納プロセス名
or replace文がない場合は、新しいストレージプロセスを作成するだけです。システムに格納プロセスがあるとエラーが発生します。Create or replace procedureはシステムにこの格納プロセスがない場合、新しいものを作成します。もしシステムにこの格納プロセスがあるなら、元のものを削除して、新たに格納プロセスを作成します。
プロシージャ名の定義を保存します。プロシージャ名とパラメータリストを含みます。パラメータ名とパラメータタイプ。パラメータ名は重複できません。パラメータ伝達方式:IN、OUT、IN OUT
INは入力パラメータを示し、値伝達方式である。
OUTは出力パラメータを表していますが、引用伝達方式によるものと理解できます。記憶プロセスの出力結果として外部の使用者に使用されてもよい。
IN OUTは入力パラメータとしてもいいし、出力パラメータとしてもいいです。
パラメータのデータタイプは、タイプ名を指定するだけで、幅を指定する必要はありません。
パラメータの幅は外部調達者によって決まります。
プロセスにはパラメータがありますが、パラメータがなくても大丈夫です。
変数宣言ブロック:続いているas(is)キーワードは、pl/sqlのdeclareキーワードとして理解され、変数を宣言するために使用されます。
変数宣言ブロックは、格納プロセスに必要な変数を宣言するために使用され、そのスコープは格納プロセスである。また、ここで宣言した変数は幅を指定しなければなりません。PL/SQLの変数宣言仕様に従う。
プロシージャブロック:beginキーからプロシージャのブロックとして開始します。記憶プロセスの具体的な論理はここで実現される。
異常処理ブロック:キーワードはexceptionで、処理文に発生する異常です。この部分はオプションです
終了ブロック:endキーワードによる結果。
1.2格納プロセスのパラメータ伝達方式
格納プロセスのパラメータ伝達には、IN、OUT、IN OUTの3つの方法があります。
INは値によって伝達され、記憶中の再割当は許可されない。保存プロセスのパラメータが指定されていない場合、デフォルトはINです。

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(20);  
begin  
 p_para1 :='aaa';  
 p_para2 :='bbb';  
 v_name := '   ';  
 p_para3 := v_name;  
 dbms_output.put_line('p_para3:'||p_para3);  
 null;  
end;  
    
Warning: Procedure created with compilation errors  
 
SQL> show error;  
Errors for PROCEDURE LIFEMAN.PROC1:  
 
LINE/COL ERROR  
-------- ----------------------------------------------------------------------  
8/3   PLS-00363: expression 'P_PARA1' cannot be used as an assignment target  
8/3   PL/SQL: Statement ignored 
この点は他の高級言語とは違っています。これはJavaがパラメータの前にfinalのキーワードを加えるのに相当します。
OUTパラメータ:出力パラメータとして、一つのパラメータがOUTタイプに指定されている場合、記憶プロセスを起動する前にこのパラメータを割り当てたとしても、記憶中のパラメータの値は依然としてnullです。

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(20);  
begin  
 v_name := '   ';  
 p_para3 := v_name;  
 dbms_output.put_line('p_para1:'||p_para1);  
 dbms_output.put_line('p_para2:'||p_para2);  
 dbms_output.put_line('p_para3:'||p_para3);  
end;  
 
SQL> var p1 varchar2(10);  
SQL> var p2 varchar2(10);  
SQL> var p3 varchar2(10);  
SQL> exec :p1 :='aaaa';  
SQL> exec :p2 :='bbbb';  
SQL> exec :p3 :='cccc';  
SQL> exec proc1(:p1,:p2,:p3);  
p_para1:aaaa  
p_para2:  
p_para3:     
SQL> exec dbms_output.put_line(:p2);  
 
 
PL/SQL procedure successfully completed  
p2  
--------- 
INOUTは本当に引用伝達パラメータである。着信パラメータとしても良いし、流れパラメータとしても良いです。
1.3記憶プロセスパラメータの幅  

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(2);  
begin  
 v_name := p_para1;  
end;  
SQL> var p1 varchar2(10);  
SQL> var p2 varchar2(20);  
SQL> var p3 varchar2(30);  
SQL> exec :p1 :='aaaaaa';  
SQL> exec proc1(:p1,:p2,:p3);  
ORA-06502: PL/SQL: numeric or value error: character string buffer too small  
ORA-06512: at "LIFEMAN.PROC1", line 8 
ORA-06512: at line 1 
まず、記憶プロセスの定義において、記憶パラメータの幅を指定できないこと、すなわち、記憶中に着信変数の幅を制御できないことを理解したい。
この幅は外部から完全に伝わった時に決められます。
OUTタイプのパラメータの幅を見に来ました。

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(2);  
begin  
 p_para2 :='aaaaaaaaaaaaaaaaaaaa';  
end;  
SQL> var p1 varchar2(1);  
SQL> var p2 varchar2(1);  
SQL> var p3 varchar2(1);  
SQL> exec :p2 :='a';  
SQL> exec proc1(:p1,:p2,:p3); 
 この過程で、p_para 2は20文字aを与えられました。
外部からの呼び出しの過程では、p 2というパラメータはvarrhar 2(1)と定義されています。
p 2をパラメータとして呼び出しますが、エラーはありません。そして、その真の値は20 aです。

SQL> select dump(:p2) from dual;  
DUMP(:P2)  
---------------------------------------------------------------------------  
Typ=1 Len=20: 97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97 
p2  
---------  
aaaaaaaaaaaaaaaaaaaa 
 IN OUTパラメータの幅を見に来てください。  

create or replace procedure proc1(  
 p_para1 varchar2,  
 p_para2 out varchar2,  
 p_para3 in out varchar2  
)as  
 v_name varchar2(2);  
begin  
 p_para3 :='aaaaaaaaaaaaaaaaaaaa';  
end;  
SQL> var p1 varchar2(1);  
SQL> var p2 varchar2(1);  
SQL> var p3 varchar2(1);  
SQL> exec proc1(:p1,:p2,:p3); 
このプロセスを実行しても、正しく実行されます。
INパラメータに対して、その幅は外部から決定されることがわかる。
OUTとIN OUTパラメータについては、その幅は格納プロセス内部で決定されます。
したがって、格納プロセスを書く際には、パラメータの幅を説明する必要があります。最も賢明な方法はパラメータのデータタイプに%typeを使うことです。これで双方は合意に達した。
1.3パラメータのデフォルト値
保存中のパラメータは標準設定ができます。

create or replace procedure procdefault(p1 varchar2,  
                    p2 varchar2 default 'mark')  
as  
begin  
 dbms_output.put_line(p2);  
end;  
SQL> set serveroutput on;  
SQL> exec procdefault('a'); 
mark 
defaultキーワードにより、格納プロセスのパラメータにデフォルト値を指定することができます。格納プロセスを呼び出した場合は、デフォルト値を省略することができます。
なお、デフォルト値はIN伝送タイプのパラメータのみに対応しています。OUTとIN OUTは標準値を指定できません。
デフォルト値があるパラメータが最後ではない場合。

create or replace procedure procdefault2(p1 varchar2 default 'remark',  
                    p2 varchar2 )  
as  
begin  
 dbms_output.put_line(p1);  
end; 
最初のパラメータにはデフォルトがあります。2番目のパラメータはありません。最初のパラメータのデフォルト値を使用したい場合

exec procdefault2('aa'); 
これは誤報になります。
どう変わりますか?パラメータの値を指定できます。

SQL> exec procdefault2(p2 =>'aa'); 
remark 
これでOKです。指定aaはパラメータp 2に伝えます。
2.格納プロセス内部ブロック
2.1内部ブロック
記憶プロセスの構造が分かりました。ステートメントブロックはbeginから始まり、endで終了します。これらのブロックは入れ子可能です。ステートメントブロックには以下のブロックを入れ替えることができます。

Declare … begin … exception … end;  
create or replace procedure innerBlock(p1 varchar2)  
as  
 o1 varchar2(10) := 'out1';  
begin  
 dbms_output.put_line(o1);  
 declare  
  inner1 varchar2(20);  
 begin  
  inner1 :='inner1';  
  dbms_output.put_line(inner1);  
 
  declare  
   inner2 varchar2(20);  
  begin  
   inner2 := 'inner2';  
   dbms_output.put_line(inner2);  
  end;  
 exception  
  when others then  
   null;  
 end;  
end; 
変数のスコープに注意が必要です。
3.保存プロセスの一般的なテクニック
3.1どの集合ですか
私たちは保存プロセスを使う時、記録集、つまり複数のデータ記録を処理する必要があります。一列の複数行と複数列の複数行に分けられ、これらのタイプは集合タイプと呼ぶことができる。私たちはここでこれらのセットのタイプを比較して、プログラミングする時に正しい選択をするのに便利です。
インデックステーブルは、pl/sqlテーブルともいいます。データベースに保存できません。要素の個数には制限がありません。下付きは負の値になります。

type t_table is table of varchar2(20) index by binary_integer;  
 v_student t_table; 
varrrhar 2(20)は、格納要素のデータタイプ、binary_を表します。integerは要素の下にあるデータタイプを表します。
ネストテーブルは、インデックステーブルにindex byサブルーチンがないと入れ子テーブルです。データに保存できます。要素の数は無限で、下付きは1から始まります。初期化が必要です。

type t_nestTable is table of varchar2(20);  
v_class t_nestTable ; 
このような声明だけでは使えません。入れ子テーブルを初期化しなければなりません。入れ子テーブルを初期化して、その構造関数を使ってもいいです。

v_class :=t_nestTable('a','b','c');
以上の説明は本文の全部です。oracleストレージの勉強に役立ちたいです。