PL/SQLベース---複雑なデータ型とカスタム型
19220 ワード
PL/SQLベース-複雑なデータ型とカスタム型
PLSQLでよく使用されるカスタムタイプは、レコードタイプ、PLSQLメモリテーブルタイプの2つです(テーブルのデータフィールドの単純さと複雑さに応じて、単純な配列とレコード配列のような機能をそれぞれ実現できます).
その他にも、CLOB、BFILEという大きなオブジェクトタイプがあります
一.メモリテーブルオブジェクト(コレクション)
一般的な関数
関数名
機能
COUNT
コレクション内の要素の数を返します.
DELETE
コレクション内のすべての要素を削除
DELETE(x)
要素の下にxと表示されている要素を削除するのはVARAYに対して不正です
DELETE(x,y)
XからYまでのエレメントを削除してVARAYに不正
EXTEND
集合の最後にIndex_の要素を追加by不正
EXTEND(x)
集合の最後にx個の要素対Index_を追加by不正
EXTEND(x,n)
集合の最後に要素nのx個のコピー対Index_を追加するby不正
EXIST(x)
集合要素xが初期化されている場合はTRUEに戻り、そうでない場合はFALSEに戻る
FIRST
集合の最初の要素の下の記号を返し、VARAY集合に対して常に1を返します.
LAST
集合内の最後の要素の下の記号を返します.VARAYに対する戻り値は常にCOUNTに等しいです.
LIMIT
VARRYコレクションの最大要素数Index_を返します.byコレクションとネストテーブルは役に立たない
NEXT(x)
x番目の要素の直後の要素値を返し、xが最後の要素である場合nullを返します.
PRIOR(x)
x番目の要素の直前にある要素の値を返し、xが最初の要素である場合nullを返します.
TRIM
コレクションの末端からindex_について要素を削除します.by非合法
TRIM(x)
コレクションの末端からx個の要素を削除
1 .変長配列(VARAY)-単純配列、下付き自動生成(int)、中間から削除不可
注意:
1 .VARAY変数はストレージスペースを初期化する必要があります
2 .下付き文字は1から:1..N
3 .サイズはタイプ定義のサイズを超えてはいけません:TYPE t_array IS VARRAY(5) OF NUMBER
2 .索引表(Associative arrays)-索引の種類がカスタマイズされている(値が1つずつ対応している)ので、削除できます.次の表は変更されません.
配列値と一意のインデックスの関連付け、および長くなる配列は下付きで異なります
3 .ネストされたテーブル(Nested tables)-インデックスタイプはINTEGER(>0)で、削除可能で、下付きは変更されません.
インデックス・タイプを指定する必要がなく、デフォルトでは整数であり、負数ではない特殊なインデックス・テーブルと見なすことができます.
データベース内のテーブルに対応可能
二.レコード(レコード)
データベース内のレコードに相当するデータセット
注意:
フィールド名は大文字と小文字を区別しません
Recordタイプは初期化する必要はありません.
RecordはTableタイプと同時に使用でき、類似のテーブル構造を構成する
%TYPE、TABLE%ROWTYPEを適切に使用します(この宣言にはデフォルト情報は含まれません).
二.ビッグオブジェクトタイプ(CLOB、NCLOB、BLOB、BFILE)
さぎょう
使用
CLOB
文字の大きいオブジェクトで、データベースの内部に格納されます.
NCLOB
データベース内に格納されたマルチバイト文字の大きなオブジェクト.
BLOB
データベース内に格納されたバイナリ・オブジェクト.
BFILE
データベースの外部に格納されたバイナリファイル.
BFILE処理は事前にDIRCTORYを確立する必要があり、現在のユーザにはこのDIRECTORYを読み取る権限がある
DBMS_LOB常用関数:具体的な使い方は関連ドキュメントを参照
関数#カンスウ#
機能
APPEND
ソースLOBの内容を宛先LOBに追加
CLOSE
開いているLOBを閉じる
FILECLOSE
開いているBFILEロケータが指すOSファイルを閉じる
FILECLOSEALL
現在のセッションで開いているすべてのBFILEファイルを閉じる
FILEEXISTS
ファイルを確定loc対応OSファイルが存在するか、1:存在0:存在しない
FILEGETNAME
BFILEロケータに対応するディレクトリの別名とファイル名を取得
FILEISOPEN
BFILE対応OSファイルが開いているかどうかを確認します
FILEOPEN
ファイルを開く
COPY
ソースLOBから宛先LOBへのデータのコピー
ERASE
LOBのすべてまたは一部を削除
TRIM
指定した長さにLOB値を減らす
WRITE
LOBへのデータの書き込み
INSTR
特定のスタイルデータを返し、LOBのあるオフセット位置からN回出現する特定の位置
OPEN
LOB,open_を開くmode(読み取り専用:dbms_lob.lob_readonly、dbms_lob.lob_readwrite)
GETLENGTH
LOBの長さを取得
READ
LOBからデータを読み出す
SUBSTR
文字処理関数SUBSTRの使用方法と同様
WRITEAPPEND
バッファデータをLOB末尾に書き込む
注:CLOBなどの大きい対象は直接IS NULLを使って空(EMPTY_CLOB()IS NULL)を判定することができなくて、正しい判断は以下の通りです:
CLOB、NCLOBの処理と文字列は類似しています:|、substrなどの文字列に対する操作をサポートします;
PLSQLでよく使用されるカスタムタイプは、レコードタイプ、PLSQLメモリテーブルタイプの2つです(テーブルのデータフィールドの単純さと複雑さに応じて、単純な配列とレコード配列のような機能をそれぞれ実現できます).
その他にも、CLOB、BFILEという大きなオブジェクトタイプがあります
一.メモリテーブルオブジェクト(コレクション)
一般的な関数
関数名
機能
COUNT
コレクション内の要素の数を返します.
DELETE
コレクション内のすべての要素を削除
DELETE(x)
要素の下にxと表示されている要素を削除するのはVARAYに対して不正です
DELETE(x,y)
XからYまでのエレメントを削除してVARAYに不正
EXTEND
集合の最後にIndex_の要素を追加by不正
EXTEND(x)
集合の最後にx個の要素対Index_を追加by不正
EXTEND(x,n)
集合の最後に要素nのx個のコピー対Index_を追加するby不正
EXIST(x)
集合要素xが初期化されている場合はTRUEに戻り、そうでない場合はFALSEに戻る
FIRST
集合の最初の要素の下の記号を返し、VARAY集合に対して常に1を返します.
LAST
集合内の最後の要素の下の記号を返します.VARAYに対する戻り値は常にCOUNTに等しいです.
LIMIT
VARRYコレクションの最大要素数Index_を返します.byコレクションとネストテーブルは役に立たない
NEXT(x)
x番目の要素の直後の要素値を返し、xが最後の要素である場合nullを返します.
PRIOR(x)
x番目の要素の直前にある要素の値を返し、xが最初の要素である場合nullを返します.
TRIM
コレクションの末端からindex_について要素を削除します.by非合法
TRIM(x)
コレクションの末端からx個の要素を削除
1 .変長配列(VARAY)-単純配列、下付き自動生成(int)、中間から削除不可
--
TYPE type_name IS VARRAY (max_elements)
OF element_datatype [ NOT NULL ];
DECLARE
TYPE t_array IS VARRAY(5) OF NUMBER;
m_data t_array;
BEGIN
m_data := t_array(0,1,2,3,4);
FOR i IN 1..5 LOOP
DBMS_OUTPUT.put_line(m_data(i));
END LOOP;
END;
注意:
1 .VARAY変数はストレージスペースを初期化する必要があります
1. m_data := t_array(0,1,2,3,4);
2. m_date.EXTEND(x[,n]);
2 .下付き文字は1から:1..N
3 .サイズはタイプ定義のサイズを超えてはいけません:TYPE t_array IS VARRAY(5) OF NUMBER
2 .索引表(Associative arrays)-索引の種類がカスタマイズされている(値が1つずつ対応している)ので、削除できます.次の表は変更されません.
配列値と一意のインデックスの関連付け、および長くなる配列は下付きで異なります
TYPE type_name IS TABLE OF element_datatype [ NOT NULL ]
--->
INDEX BY BINARY_INTEGER;
INDEX BY PLS_INTEGER;
INDEX BY POSITIVE;
INDEX BY NATURAL;
INDEX BY SIGNTYPE;
INDEX BY VARCHAR2(32767);
INDEX BY table.column%TYPE;
INDEX BY cursor.column%TYPE;
INDEX BY package.variable%TYPE;
INDEX BY package.subtype;
--
DECLARE
TYPE t_associative_table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_table t_associative_table;
BEGIN
-- v_table := t_associative_table(0,1,2,2,4);
v_table(1) := 1;
v_table(2) := 2;
v_table(3) := 3;
v_table(4) := 3;
v_table(5) := 5;
FOR i IN 1..5 LOOP
IF v_table.EXISTS(i) THEN
v_table.DELETE(i);
END IF;
END LOOP;
DBMS_OUTPUT.put_line(v_table.COUNT());
END;
3 .ネストされたテーブル(Nested tables)-インデックスタイプはINTEGER(>0)で、削除可能で、下付きは変更されません.
インデックス・タイプを指定する必要がなく、デフォルトでは整数であり、負数ではない特殊なインデックス・テーブルと見なすことができます.
データベース内のテーブルに対応可能
--
TYPE type_name IS TABLE OF element_datatype [ NOT NULL ];
--
DECLARE
TYPE t_nested_table IS TABLE OF NUMBER;
v_table t_nested_table;
BEGIN
v_table := t_nested_table(0,1,2,2,4);
v_table.DELETE(1);
DBMS_OUTPUT.put_line(v_table.COUNT());
FOR i IN 2..5 LOOP
IF v_table.EXISTS(i) THEN
DBMS_OUTPUT.put_line(v_table(i));
END IF;
END LOOP;
END;
二.レコード(レコード)
データベース内のレコードに相当するデータセット
TYPE type_name IS RECORD
(field_declaration[, field_declaration]…);
identifier type_name;
--field_declaration
field_name field_type;
field_name variable%TYPE/Table.column%TYPE;
field_name Table%ROWTYPE;
[NUT NULL]
[DEFAULT value]
--
DECLARE
TYPE T_RECORD_DEF IS RECORD
(
employee_id NUMBER,
lats_name VARCHAR2(20) DEFAULT 'NO_NAME');
e_record_1 T_RECORD_DEF;
e_record_2 T_RECORD_DEF;
BEGIN
SELECT e.EMPLOYEE_ID,e.Last_Name
INTO e_record_1
FROM EMPLOYEES e WHERE e.EMPLOYEE_ID = 100;
DBMS_OUTPUT.put_line(e_record_1.lats_name);
DBMS_OUTPUT.put_line(e_record_2.lats_name);
END;
注意:
フィールド名は大文字と小文字を区別しません
Recordタイプは初期化する必要はありません.
RecordはTableタイプと同時に使用でき、類似のテーブル構造を構成する
%TYPE、TABLE%ROWTYPEを適切に使用します(この宣言にはデフォルト情報は含まれません).
二.ビッグオブジェクトタイプ(CLOB、NCLOB、BLOB、BFILE)
さぎょう
使用
CLOB
文字の大きいオブジェクトで、データベースの内部に格納されます.
NCLOB
データベース内に格納されたマルチバイト文字の大きなオブジェクト.
BLOB
データベース内に格納されたバイナリ・オブジェクト.
BFILE
データベースの外部に格納されたバイナリファイル.
-- Writw...
DECLARE
directions CLOB;
amount BINARY_INTEGER;
offset INTEGER;
first_direction VARCHAR2(100);
more_directions VARCHAR2(500);
BEGIN
--Delete any existing rows for 'Munising Falls' so that this
--example can be executed multiple times
DELETE
FROM waterfalls
WHERE falls_name='Munising Falls';
--Insert a new row using EMPTY_CLOB( ) to create a LOB locator
INSERT INTO waterfalls
(falls_name,falls_directions)
VALUES ('Munising Falls',EMPTY_CLOB( ));
--Retrieve the LOB locator created by the previous INSERT statement
SELECT falls_directions
INTO directions
FROM waterfalls
WHERE falls_name='Munising Falls';
--Open the LOB; not strictly necessary, but best to open/close LOBs.
DBMS_LOB.OPEN(directions, DBMS_LOB.LOB_READWRITE);
--Use DBMS_LOB.WRITE to begin
first_direction := 'Follow I-75 across the Mackinac Bridge.';
amount := LENGTH(first_direction); --number of characters to write
offset := 1; --begin writing to the first character of the CLOB
DBMS_LOB.WRITE(directions, amount, offset, first_direction);
--Add some more directions using DBMS_LOB.WRITEAPPEND
more_directions := ' Take US-2 west from St. Ignace to Blaney Park.'
|| ' Turn north on M-77 and drive to Seney.'
|| ' From Seney, take M-28 west to Munising.';
DBMS_LOB.WRITEAPPEND(directions,
LENGTH(more_directions), more_directions);
--Add yet more directions
more_directions := ' In front of the paper mill, turn right on H-58.'
|| ' Follow H-58 to Washington Street. Veer left onto'
|| ' Washington Street. You''ll find the Munising'
|| ' Falls visitor center across from the hospital at'
|| ' the point where Washington Street becomes'
|| ' Sand Point Road.';
DBMS_LOB.WRITEAPPEND(directions,
LENGTH(more_directions), more_directions);
--Close the LOB, and we are done.
DBMS_LOB.CLOSE(directions);
END;
---Reading...
DECLARE
directions CLOB;
directions_1 VARCHAR2(300);
directions_2 VARCHAR2(300);
chars_read_1 BINARY_INTEGER;
chars_read_2 BINARY_INTEGER;
offset INTEGER;
BEGIN
--Retrieve the LOB locator inserted previously
SELECT falls_directions
INTO directions
FROM waterfalls
WHERE falls_name='Munising Falls';
--Begin reading with the first character
offset := 1;
--Attempt to read 229 characters of directions, chars_read_1 will
--be updated with the actual number of characters read
chars_read_1 := 229;
DBMS_LOB.READ(directions, chars_read_1, offset, directions_1);
--If we read 229 characters, update the offset and try to
--read 255 more.
IF chars_read_1 = 229 THEN
offset := offset + chars_read_1;
chars_read_2 := 255;
DBMS_LOB.READ(directions, chars_read_2, offset, directions_2);
ELSE
chars_read_2 := 0;
directions_2 := '';
END IF;
--Display the total number of characters read
DBMS_OUTPUT.PUT_LINE('Characters read = ' ||
TO_CHAR(chars_read_1+chars_read_2));
--Display the directions
DBMS_OUTPUT.PUT_LINE(directions_1);
DBMS_OUTPUT.PUT_LINE(directions_2);
END;
BFILE処理は事前にDIRCTORYを確立する必要があり、現在のユーザにはこのDIRECTORYを読み取る権限がある
CREATE DIRECTORY bfile_data AS ' :c:\data\file.txt';
GRANT READ ON DIRECTORY bfile_data TO ;
--
DECLARE
web_page BFILE;
BEGIN
--Delete row for Tannery Falls so this example can
--be executed multiple times
DELETE FROM waterfalls WHERE falls_name='Tannery Falls';
--Invoke BFILENAME to create a BFILE locator
web_page := BFILENAME('BFILE_DATA','Tannery Falls.htm');
--
--Save our new locator in the waterfalls table
INSERT INTO waterfalls (falls_name, falls_web_page)
VALUES ('Tannery Falls',web_page);
END;
--
DECLARE
web_page BFILE;
html RAW(60);
amount BINARY_INTEGER := 60;
offset INTEGER := 1;
BEGIN
--Retrieve the LOB locat0r for the web page
SELECT falls_web_page
INTO web_page
FROM waterfalls
WHERE falls_name='Tannery Falls';
--Open the locator, read 60 bytes, and close the locator
DBMS_LOB.OPEN(web_page);
DBMS_LOB.READ(web_page, amount, offset, html);
DBMS_LOB.CLOSE(web_page);
--Uncomment following line to display results in hex
--DBMS_OUTPUT.PUT_LINE(RAWTOHEX(html));
--Cast RAW results to a character string we can read
DBMS_OUTPUT.PUT_LINE(UTL_RAW.CAST_TO_VARCHAR2(html));
END;
--
DECLARE
Tannery_Falls_Directions BFILE
:= BFILENAME('BFILE_DATA','TanneryFalls.directions');
directions CLOB;
destination_offset INTEGER := 1;
source_offset INTEGER := 1;
language_context INTEGER := DBMS_LOB.default_lang_ctx;
warning_message INTEGER;
BEGIN
--Delete row for Tannery Falls, so this example
--can run multiple times.
DELETE FROM waterfalls WHERE falls_name='Tannery Falls';
--Insert a new row using EMPTY_CLOB( ) to create a LOB locator
INSERT INTO waterfalls
(falls_name,falls_directions)
VALUES ('Tannery Falls',EMPTY_CLOB( ));
--Retrieve the LOB locator created by the previous INSERT statement
SELECT falls_directions
INTO directions
FROM waterfalls
WHERE falls_name='Tannery Falls';
--Open the target CLOB and the source BFILE
DBMS_LOB.OPEN(directions, DBMS_LOB.LOB_READWRITE);
DBMS_LOB.OPEN(Tannery_Falls_Directions);
--Load the contents of the BFILE into the CLOB column
DBMS_LOB.LOADCLOBFROMFILE
(directions, Tannery_Falls_Directions,
DBMS_LOB.LOBMAXSIZE,
destination_offset, source_offset,
NLS_CHARSET_ID('US7ASCII'),
language_context, warning_message);
--Check for the only possible warning message.
IF warning_message = DBMS_LOB.WARN_INCONVERTIBLE_CHAR THEN
dbms_output.put_line(
'Warning! Some characters couldn''t be converted.');
END IF;
--Close both LOBs
DBMS_LOB.CLOSE(directions);
DBMS_LOB.CLOSE(Tannery_Falls_Directions);
END;
DBMS_LOB常用関数:具体的な使い方は関連ドキュメントを参照
関数#カンスウ#
機能
APPEND
ソースLOBの内容を宛先LOBに追加
CLOSE
開いているLOBを閉じる
FILECLOSE
開いているBFILEロケータが指すOSファイルを閉じる
FILECLOSEALL
現在のセッションで開いているすべてのBFILEファイルを閉じる
FILEEXISTS
ファイルを確定loc対応OSファイルが存在するか、1:存在0:存在しない
FILEGETNAME
BFILEロケータに対応するディレクトリの別名とファイル名を取得
FILEISOPEN
BFILE対応OSファイルが開いているかどうかを確認します
FILEOPEN
ファイルを開く
COPY
ソースLOBから宛先LOBへのデータのコピー
ERASE
LOBのすべてまたは一部を削除
TRIM
指定した長さにLOB値を減らす
WRITE
LOBへのデータの書き込み
INSTR
特定のスタイルデータを返し、LOBのあるオフセット位置からN回出現する特定の位置
OPEN
LOB,open_を開くmode(読み取り専用:dbms_lob.lob_readonly、dbms_lob.lob_readwrite)
GETLENGTH
LOBの長さを取得
READ
LOBからデータを読み出す
SUBSTR
文字処理関数SUBSTRの使用方法と同様
WRITEAPPEND
バッファデータをLOB末尾に書き込む
注:CLOBなどの大きい対象は直接IS NULLを使って空(EMPTY_CLOB()IS NULL)を判定することができなくて、正しい判断は以下の通りです:
IF some_clob IS NULL THEN
--There is no data
ELSEIF DBMS_LOB.GETLENGTH(some_clob) = 0 THEN
--There is no data
ELSE
--Only now is there data
END IF;
CLOB、NCLOBの処理と文字列は類似しています:|、substrなどの文字列に対する操作をサポートします;