SQLデータ型
PL/SQLデータ型にはSQLデータ型が含まれます。
SQLデータ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください(記載されているデータ型およびサブタイプ、データ型の比較のルール、データ変換、リテラル、および書式モデルに関する情報はすべて、次の項目を除き、SQLとPL/SQLの両方に適用されます)。
SQLとは異なり、PL/SQLでは変数を宣言できます。変数には次のトピックが適用されます。
最大サイズの相違
表4-1にリストしたSQLのデータ型は、PL/SQLとSQLで最大サイズが異なります。
表4-1 PL/SQLとSQLで最大サイズが異なるデータ型
データ型 | PL/SQLでの最大サイズ | SQLでの最大サイズ |
---|---|---|
|
32,767バイト |
2,000バイト |
|
32,767バイト |
2,000バイト |
|
32,767バイト |
2,000バイト脚注2 |
|
32,767バイト |
4,000バイト脚注2 |
|
32,767バイト |
4,000バイト脚注2 |
|
32,760バイト |
2ギガバイト(GB) - 1 |
|
32,760バイト |
2 GB |
|
128テラバイト(TB) |
(4GB - 1) * |
|
128 TB |
(4GB - 1) * |
|
128 TB |
(4GB - 1) * |
脚注1
このデータ型の値の最大サイズをPL/SQLで指定する場合は、定数または変数ではなく、1から32,767の間の値を持つ整数リテラルを使用します。
脚注2
このサイズの違いをなくすには、『Oracle Database SQL言語リファレンス』の手順に従ってください。
脚注3
既存のアプリケーションとの下位互換性を保つためにのみサポートされています。
BINARY_FLOATおよびBINARY_DOUBLEの追加のPL/SQL定数
SQLデータ型のBINARY_FLOAT
およびBINARY_DOUBLE
は、それぞれ単精度および倍精度のIEEE 754形式の浮動小数点数を表します。
BINARY_FLOAT
およびBINARY_DOUBLE
の計算では、例外は発生しないため、これらの計算によって生成された値がオーバーフローやアンダーフローなどの状態になっていないかどうか、事前定義の定数と比較して確認する必要があります(例は、『Oracle Database SQL言語リファレンス』を参照してください)。PL/SQLには、この型の定数がSQLよりも多数あります。
表4-2に、BINARY_FLOATおよび
BINARY_DOUBLEとして
事前定義されているPL/SQL定数を示します。SQLでも定義されているものには注を付けてあります。
表4-2 事前定義のPL/SQLのBINARY_FLOATおよびBINARY_DOUBLEの定数
定数 | 説明 |
---|---|
|
条件 |
|
単精度の正の無限大 |
|
最大正規 |
|
最小正規 |
|
最大非正規 |
|
最小非正規 |
|
条件 |
|
倍精度の正の無限大 |
|
最大正規 |
|
最小正規 |
|
最大非正規 |
|
最小非正規 |
(*) この定数は、SQLでも事前定義されています。
BINARY_FLOATおよびBINARY_DOUBLEの追加のPL/SQLサブタイプ
PL/SQLでは、次のサブタイプが事前定義されています。
-
SIMPLE_FLOAT
(SQLデータ型BINARY_FLOAT
のサブタイプ) -
SIMPLE_DOUBLE
(SQLデータ型BINARY_DOUBLE
のサブタイプ)
各サブタイプはそのベース型と同じ範囲を取り、NOT
NULL
制約(「NOT NULL制約」を参照)を含んでいます。
値NULL
を取らないとわかっている変数は、BINARY_FLOAT
またはBINARY_DOUBLE
ではなく、SIMPLE_FLOAT
またはSIMPLE_DOUBLE
として宣言します。これらのサブタイプを使用すると、NULLかどうかのチェックのためのオーバーヘッドが発生せず、そのベース型を使用するよりパフォーマンスが大幅に向上します。PLSQL_CODE_TYPE='INTERPRETED'
よりもPLSQL_CODE_TYPE='NATIVE'
を使用する方が、パフォーマンスの向上幅が大きくなります(詳細は、「ハードウェア算術を使用するデータ型の使用」を参照してください)。
BOOLEANデータ型
BOOLEAN
データ型には、論理値(ブール値のTRUE
とFALSE
、およびNULL
値)が格納されます。NULL
は、不明な値を表します。
BOOLEAN
変数を宣言するための構文は、次のとおりです。
variable_name BOOLEAN
デフォルトでは、DBMS_OUTPUT
.PUT
またはDBMS_OUTPUT
.PUT_LINE
サブプログラムなど、プロシージャやファンクションのNUMBER
またはVARCHAR2
パラメータにBOOLEAN
値を渡すことはできません。これらのプロシージャにBOOLEAN
値を渡すには、初期化パラメータPLSQL_IMPLICIT_CONVERSION_BOOL
をTRUE
に設定します。このパラメータをTRUE
に設定すると、変数の割当てで暗黙的な変換もできるようになります(たとえば、NUMBER
またはVARCHAR2
の値をBOOLEAN
変数に割り当てる場合)。また、値をTRUE
にすると、BOOLEAN
変数の割当てで文字列リテラルを使用できるようになります。このパラメータは、CAST
やファンクションTO_NUMBER
、TO_CHAR
、TO_BOOLEAN
など、明示的な変換には影響しません。
サブプログラムがBOOLEAN
型と数値型または文字型でオーバーロードされている場合、PLSQL_IMPLICIT_CONVERSION_BOOL
をTRUE
に設定すると、コンパイル時エラーが発生する可能性があります。このパラメータの使用時に発生する可能性があるオーバーロード・エラーの詳細は、「サブプログラムのオーバーロード・エラー」を参照してください。
PLSQL_IMPLICIT_CONVERSION_BOOL
パラメータは存続可能、つまりこのパラメータを使用して作成されたすべてのPL/SQLユニットは、そのユニットがREUSE SETTINGS
句でコンパイルされて作成された時点で指定された値を使用します。
BOOLEAN
式をBOOLEAN
変数に割り当てる(PLSQL_IMPLICIT_CONVERSION_BOOL
パラメータの値に関係なく)ことも可能です。静的なBOOLEAN
式の詳細は、「BOOLEAN式」を参照してください。
関連項目:
-
PLSQL_IMPLICIT_CONVERSION_BOOL
パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください - SQLの
BOOLEAN
データ型の詳細およびTRUE
とFALSE
を表すために使用可能な文字列リテラルのリストは、『Oracle Database SQL言語リファレンス』を参照してください
例4-1 BOOLEAN値の出力
この例では、プロシージャDBMS_OUTPUT.PUT_LINE
に直接値を渡すことで、BOOLEAN
値が出力されます。このコードの実行は、TRUE
に設定されている初期化パラメータPLSQL_IMPLICIT_CONVERSION_BOOL
によって異なります。
DECLARE
t_b boolean := TRUE;
f_b boolean := FALSE;
BEGIN
DBMS_OUTPUT.PUT_LINE('My bool is: ' || t_b);
DBMS_OUTPUT.PUT_LINE('My bool is: ' || f_b);
END;
結果:
My bool is: TRUE
My bool is: FALSE
JSONデータ型
JSON
データ型インスタンスは、PL/SQLサブプログラムで使用できます。PL/SQL JSON
データ型は、ネストしたJSON
値への高速アクセスのために、バイナリ形式でデータベースに格納されます。
JSONデータ型とそのインスタンスは、次のようなSQLデータ型が使用可能なほとんどの場所で使用できます。
-
表やビューDDLの列の型として
-
PL/SQLサブプログラムのパラメータの型として
-
レコード内の要素またはフィールド・タイプ、PL/SQLコレクションおよび
%ROWTYPE
属性として -
SQL/JSON関数または条件が許可される式。
JSONデータ型は、現在SQLコレクションまたはオブジェクトではサポートされていません。
ここでのトピック
関連項目:
-
JSONスキーマの詳細は、json-schema.orgを参照してください
-
JSONデータを使用してPL/SQLを使用する方法の詳細は、Oracle Database JSON開発者ガイドを参照してください
-
JSON用のPL/SQLオブジェクト・タイプの詳細は、『Oracle Database JSON開発者ガイド』を参照してください
PL/SQLとJSONの型変換
組込み関数json_value
は、スカラー・データ型マッピングおよびJSONオブジェクトからユーザー定義PL/SQLタイプへのマッピングをサポートしています。ユーザー定義PL/SQLまたはSQL集計タイプのインスタンスの場合、PL/SQL JSONコンストラクタは対応するJSONオブジェクトまたはJSON配列型インスタンスを返します。
json_value
では、返される集計データ型としてPL/SQLユーザー定義サブタイプの使用がサポートされています。これには、返される集計データ型でフィールドまたは要素データ型として使用されるサブタイプによって使用される制約または初期化子のサポートが含まれます。
すべてのPL/SQLレコード・フィールドとコレクション・データ要素のデータ型制約は、PL/SQL json_value
によって適用されます。制約には、文字の最大長、数値スケールと精度、時間、タイム・スタンプ、間隔の制約、整数範囲チェック、NOT NULL制約が含まれます。
これらのタイプは、トップレベルのSQL (SQLオブジェクトおよびコレクション用)、パッケージ・レベルのPL/SQL、またはPL/SQLファンクション、プロシージャまたは匿名コール・ブロック内のローカルなど、json_value
コール・サイトに表示される任意のプログラム・スコープで宣言できます。
PL/SQL固有のユーザー定義集計タイプには、次のものがあります。
-
レコード
-
INDEX BY PLS_INTEGER
コレクション -
連想配列
-
ネストした表
-
可変長配列
-
オブジェクト
PL/SQL集計タイプは、PL/SQL組込み関数のIN
およびRETURN
データ型として使用できます。すべてのPL/SQL %ROWTYPE
は、json_value
のRETURNING
句でサポートされます。
ON MISMATCH
句をjson_value
とともに使用して、タイプ一致の例外を処理できます。指定された戻り型にターゲットのJSON値を変換できない場合に、必要な動作を指定するために使用します。PL/SQLレコード、index by PLS_INTEGER
コレクションおよびindex by VARCHAR2
コレクションはアトミックnullにできません。したがって、これらのタイプのいずれかが戻り型として指定されている場合、NULL ON MISMATCH
句でコンパイル時にエラーが発生します。ON MISMATCH
句の詳細は、Oracle Database JSON開発者ガイドを参照してください。
タイプ名の解決および範囲指定
json_value
で使用されるタイプ名は、標準のPL/SQL名前解決ルールを使用して解決されます。PL/SQLでは、名前が参照されるPL/SQLコードの最も内側の範囲から名前を探し始め、名前が解決されるまで、検索を外部の範囲に拡げます。
PL/SQL組込み関数json_value
は、次の形式を含む最大3つのパート名を解決します。
-
<schema name>.<package name>.<type name>
-
<package name>.<type name>
-
<schema name>.<type name>
-
<type name>
これは、1つまたは2つのパート・タイプ名のみを解決するSQLのjson_value
組込み関数とは異なります。
シノニムは、フル・タイプ名の文字列で適切に使用でき、これらのシノニムがタイプ名の解決中に解決されます。
ここでのトピック
関連項目:
-
json_value
組込み関数の詳細は、『Oracle Database JSON開発者ガイド』を参照してください
JSONオブジェクトとPL/SQLレコード
PL/SQLレコードは、名前/値のペアを使用してデータを保持し、JSONコンストラクタおよび組込み関数json_value
を介してJSONオブジェクトとの間でそれぞれマップできます。
ここでのトピック
JSONオブジェクトからPL/SQLレコードへ
RETURNING
句でPL/SQLレコード名が指定されている場合、json_value
は入力JSONオブジェクトをPL/SQLレコードにマップし、PL/SQLレコードのインスタンスを返します。入力JSONがJSONオブジェクトでない場合は、ON MISMATCH
句が適用されます。
マッピングを実行するには、各JSONキー名をPL/SQLレコードの一意の属性にマップする必要があります。この比較では、名前を囲む二重引用符を無視するデフォルトの大/小文字を区別しない比較と、マップするいずれかのタイプのキーまたは属性名の配置を使用する必要があります。
次に示すように、大/小文字を区別するマッピング構文を使用して、大/小文字を区別するマッピングがサポートされています。
DECLARE
TYPE personrecord IS RECORD(first VARCHAR2(10), last VARCHAR2(10));
p personrecord;
BEGIN
p := JSON_VALUE(JSON('{"FIRST":"Jane", "LAST":"Cooper"}'), '$'
RETURNING personrecord USING CASE_SENSITIVE MAPPING);
DBMS_OUTPUT.PUT_LINE(p.first ||' '|| p.last);
END;
/
キー名がマップされると、キー名のJSON値がPL/SQLレコード属性にコピーされます。JSON値は、マップされたフィールドのPL/SQLデータ型に変換可能である必要があります。値タイプが変換可能でない場合、MISMATCH
エラーが発生します。
JSONフィールドを含むレコード・タイプは、json_value
へのコールでサポートされます。JSONフィールドは、JSONオブジェクトやJSON配列を含む任意のJSONタイプにマップされます。つまり、JSON属性名がレコード・フィールド名にマップされ、レコード・フィールドがJSONタイプである場合、PL/SQLはJSON属性のJSON値をレコード・フィールドのJSONタイプにコピーします。
JSON値は有効なJSONである必要があります。JSONドキュメントがテキストの場合は、JSONフィールドにコピーされたときにJSON値が解析され、有効なJSONであることが検証されます。コピーが完了すると、その属性に対してそれ以上の再帰的マッピングは実行されません。
例4-2 JSONオブジェクトからPL/SQLレコードへの変換
この例では、同じJSONオブジェクトを2つの異なるPL/SQLレコードにマップする方法を示します。
DECLARE
TYPE theRec1 IS RECORD (field1 NUMBER, field2 VARCHAR2(10));
TYPE theRec2 IS RECORD ("fIeLd2" VARCHAR2(20), "FielD1" NUMBER);
Rec1 theRec1;
Rec2 theRec2;
BEGIN
Rec1 := JSON_VALUE(JSON('{"FIELD1":10, "field2":"hello"}'), '$' RETURNING theRec1);
Rec2 := JSON_VALUE(JSON('{"FIELD1":10, "field2":"hello"}'), '$' RETURNING theRec2);
END;
/
PL/SQLブロックを実行すると、Rec1
およびRec2
にそれぞれ次の値が含まれます。
theRec1(field1=>10, field2=>'hello')
theRec2("fIeLd2"=>'hello', "FielD1"=>10)
PL/SQLレコードからJSONオブジェクトへ
SQLオブジェクトとPL/SQLレコード・タイプ・インスタンス(<table | view | cursor>%ROWTYPE
属性によって作成された暗黙的なレコードを含む)は、JSONコンストラクタへの有効な入力として許可されます。
PL/SQLオブジェクト属性名がJSONキー名になります。二重引用符で囲まれた属性名は大/小文字が区別されるJSONキー名になり、二重引用符で囲まれていない属性名は大文字のJSONキー名になります。PL/SQLオブジェクト属性値は、最も近いJSON値タイプにマップされます。
例4-3 PL/SQLレコードからJSONオブジェクトへの変換
DECLARE
TYPE theRec IS RECORD(field1 NUMBER, "Field2" NUMBER);
myRec theRec := theRec(10, 20);
myJson JSON;
BEGIN
myJson := JSON(myRec);
DBMS_OUTPUT.PUT_LINE(JSON_SERIALIZE(myJson));
END;
/
結果:
{"FIELD1":10, "Field2":20}
JSONオブジェクトおよびIndex by PLS_INTEGERおよびネストした表のコレクション
Index by PLS_INTEGER
コレクションおよびネストした表コレクションは、それぞれ組込みのjson_value
関数およびJSONコンストラクタを使用してJSONオブジェクトとの間で双方向に変換できます。
ここでのトピック
JSONオブジェクトからIndex by PLS_INTEGERおよびネストした表のコレクション
Index by PLS_INTEGER
およびネストした表コレクションの両方に、整数索引付き要素に依存する疎コレクション型を指定できます。これらのタイプは、オブジェクトの文字列キー属性がコレクションの整数索引の文字列表現であるJSONオブジェクトにマップされます。
JSONオブジェクトからいずれかのコレクション型への変換時に、JSONオブジェクト文字列キー属性が整数値に正しく変換されない場合、エラーが発生します。ネストした表コレクションでは、キー属性が正の整数である必要があります。それ以外の場合はエラーが発生します。また、最大キー値は、JSONオブジェクトの要素数を超えることはできません。キー値をさらに大きくする必要がある場合は、Index by PLS_INTEGER
コレクションを使用できます。
オブジェクト内の索引値の間にギャップがある場合、これらのギャップは両方のコレクション型で再作成されます。つまり、JSONオブジェクトの最小値と最大値の索引の間に要素がない場合、それらの要素もコレクションにありません。欠落している要素はNULL
要素と同じではないことに注意してください。
JSONオブジェクト索引キー属性はソート順である必要はありません。コレクションに挿入されるとソートされます。
例4-4 JSONオブジェクトからIndex by PLS_INTEGERコレクションへの変換
この例では、組込み関数json_value
を使用した、JSONオブジェクトからIndex by PLS_INTEGER
コレクションへの変換を示します。
DECLARE
TYPE theIBPLS IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
myIBPLS theIBPLS;
BEGIN
myIBPLS := JSON_VALUE(JSON('{"-10":10, "-1":1, "100":-100}'), '$' RETURNING theIBPLS);
END;
/
PL/SQLブロックを実行すると、次の要素値を使用してIndex by PLS_INTEGER
コレクションが作成されます。
theIBPLS(-10=>10, -1=>1, 100=>-100)
例4-5 JSONオブジェクトからネストした表コレクションへの変換
この例では、組込み関数json_value
を使用したJSONオブジェクトのネストした表コレクションへの変換を示します。
DECLARE
TYPE theNSTTAB IS TABLE OF NUMBER;
myNSTTAB theNSTTAB;
BEGIN
myNSTTAB := JSON_VALUE(JSON('{"1":10, "2":20, "3":30, "4":40}'), '$' RETURNING theNSTTAB);
END;
/
PL/SQLブロックを実行すると、次の値を使用してネストした表コレクションが作成されます。
theNSTTAB(1=>10, 2=>20, 3=>30, 4=>40)
Index by PLS_INTEGERコレクションおよびネストしたタイプからJSONオブジェクト
Index by PLS_INTEGER
コレクションは、JSONコンストラクタに渡されたときに索引値が保持されるJSONオブジェクトに変換されます。JSONオブジェクトとして表される場合、このコレクションの索引は、索引整数値のJSON文字列表現として表示されます。
PL/SQLとJSONの往復と、PL/SQLに戻るときの疎を保持するために、ネストした表コレクションがJSONコンストラクタに渡されるときに、JSONオブジェクトに変換されます。JSONオブジェクトとして表される場合、ネストした表索引は、索引の整数値のJSON文字列表現として表示されます。
例4-6 Index by PLS_INTEGERコレクションからJSONオブジェクトへの変換
この例では、JSONコンストラクタを使用した、Index by PLS_INTEGER
コレクションからJSONオブジェクトへの変換を示します。
DECLARE
TYPE theIBPLS IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
myIBPLS theIBPLS := theIBPLS(-1=>1, 2=>2, -3=>3);
myJSON JSON;
BEGIN
myJSON := JSON(myIBPLS);
DBMS_OUTPUT.PUT_LINE(JSON_SERIALIZE(myJSON));
END;
/
結果:
{ "-3":3, "-1":1, "2":2 }
例4-7 ネストした表からJSONオブジェクトへの変換
この例では、JSONコンストラクタを使用したスパース・ネストした表のJSONオブジェクトへの変換を示します。
DECLARE
TYPE theNSTTAB IS TABLE OF NUMBER;
myNSTTAB theNSTTAB := theNSTTAB(1=>1, 2=>2, 3=>3);
myJSON JSON;
BEGIN
myNSTTAB.delete(2); --myNSTTAB becomes sparse when elements are deleted
myJSON := JSON(myNSTTAB);
DBMS_OUTPUT.PUT_LINE(JSON_SERIALIZE(myJSON));
END;
/
結果:
{ "1":1, "3":3 }
JSON配列とネストした表、Index by PLS_INTEGERおよびVarrayコレクション
JSON配列は組込みのjson_value
関数を使用して、ネストした表、Index by PLS_INTEGER
またはVarrayコレクションに変換されます。VARRAYは、JSONコンストラクタを通過するとJSON配列に変換され、Index by PLS_INTEGER
コレクションおよびネストした表はJSONオブジェクトに変換されます。
ここでのトピック
JSON配列からネストした表、Index by PLS_INTEGERおよびVarrayコレクション
RETURNING
句でIndex by PLS_INTEGER
、ネストした表またはVARRAYコレクションが指定されている場合、json_value
は入力JSON配列をPL/SQLコレクション型に変換し、PL/SQLコレクションのインスタンスを返します。入力JSONがJSON配列でない場合は、MISMATCH
エラーが発生します。
JSON配列をPL/SQLコレクションに変換するには、JSON配列要素が1つずつコレクションに挿入されます。挿入は、PL/SQLコレクションの索引1
に挿入されたJSON配列の最初の要素から始まり、最後のJSON配列要素がコレクションに挿入されると終了します。挿入された要素ごとに、コレクション索引が1
ずつ増分されます。
-
JSONのNULL要素により、PL/SQLの
NULL
要素がコレクションに挿入されます。 -
JSON配列の要素数が対応するVARRAYのサイズを超えると、
MISMATCH
エラーが発生します。 -
JSON要素タイプがPL/SQLコレクション要素タイプに変換できない場合、
MISMATCH
エラーが発生します。
例4-8 JSON配列からIndex by PLS_INTEGERコレクションへの変換
この例では、組込み関数json_value
を使用して、JSON配列をIndex by PLS_INTEGER
コレクションに変換します。
DECLARE
TYPE theIBPLS IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
myIBPLS theIBPLS;
BEGIN
myIBPLS := JSON_VALUE(JSON('[1, 2, 3, 4, 5]'), '$' RETURNING theIBPLS);
END;
/
このPL/SQLブロックを実行すると、myIBPLS
に次の値が設定されます:
theIBPLS(1=>1, 2=>2, 3=>3, 4=>4, 5=>5)
例4-9 JSON配列からVARRAYへの変換
この例では、組込み関数json_value
を使用して、JSON配列をVARRAYに変換します。
DECLARE
TYPE theVARRAY IS VARRAY(5) OF NUMBER;
myVARRAY theVARRAY;
BEGIN
myVARRAY := JSON_VALUE(JSON('[1, 2, 3, 4, 5]'), '$' RETURNING theVARRAY);
END;
/
このPL/SQLブロックを実行すると、myVARRAY
に次の値が設定されます。
theVARRAY(1=>1, 2=>2, 3=>3, 4=>4, 5=>5)
例4-10 JSON配列からネストした表への変換
この例では、組込み関数json_value
を使用して、JSON配列をネストした表に変換します。
DECLARE
TYPE theNESTEDTABLE IS TABLE OF NUMBER;
myNESTEDTABLE theNESTEDTABLE;
BEGIN
myNESTEDTABLE := JSON_VALUE(JSON('[1, 2, 3, 4, 5]'), '$' RETURNING theNESTEDTABLE);
END;
/
このPL/SQLブロックを実行すると、myNESTEDTABLE
に次の値が設定されます。
theNESTEDTABLE(1=>1, 2=>2, 3=>3, 4=>4, 5=>5)
JSON配列への配列
VARRAYは、JSONコンストラクタに渡されると、JSON配列に変換されます。
VARRAYがJSON配列に変換されると、コレクションの各要素が、最小のコレクション索引の要素から始まり、最大のコレクション索引の要素で終わるJSON配列に挿入されます。索引はJSON配列には転送されず、要素値のみが転送されます。
JSONコンストラクタに渡されると、Index by PLS_INTEGER
コレクションおよびネストしたタイプはJSON配列ではなくJSONオブジェクトに変換されます。
例4-11 VARRAYからJSON配列への変換
DECLARE
TYPE theVarray IS VARRAY(4) OF NUMBER;
myVarray theVarray := theVarray(1, 2, 3, null);
myJSON JSON;
BEGIN
myJSON := JSON(myVarray);
DBMS_OUTPUT.PUT_LINE(JSON_SERIALIZE(myJSON));
END;
/
結果:
[1, 2, 3, null]
JSONオブジェクトと連想配列
連想配列は、それぞれJSONコンストラクタと組込み関数json_value
を使用して、JSONオブジェクトとの間で変換できます。
ここでのトピック
連想配列へのJSONオブジェクト
JSONオブジェクトが連想配列にマップされると、各JSONキー名と値のペアは、連想配列の順序またはコレクション(あるいはその両方)に基づいて連想配列に挿入されます。
連想配列キー名は大/小文字が区別され、挿入ではJSONキー名の大/小文字が保持されます。キーのJSON値は必要に応じて連想配列要素タイプに変換され、キーの名前/値ペアが連想配列に挿入されます。
SQLオブジェクトおよびPL/SQLレコードと同様に、JSON値はネストしたオブジェクトまたは配列であり、連想配列要素タイプに変換可能である必要があります。値タイプが変換可能でない場合、MISMATCH
エラーが発生します。
例4-12 JSONオブジェクトから連想配列への変換
この例では、組込み関数json_value
を使用して、JSONオブジェクトを連想配列に変換します。
DECLARE
TYPE theASCARRAY IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
myAscArray theASCARRAY;
BEGIN
myAscArray := JSON_VALUE(JSON('{"Key1":10, "Key2":20}'), '$' RETURNING theASCARRAY);
END;
/
このPL/SQLブロックを実行すると、次の2つの要素に関連付けられます。
theASCARRAY('Key1'=>10, 'Key2'=>20)
JSONオブジェクトへの連想配列
連想配列をJSONオブジェクトに変換するプロセスは、すべての連想配列キーと値を名前/値のペアとしてJSONオブジェクトに挿入することです。PL/SQL連想配列内のすべてのキー名が一意であり、JSON属性の順序がJSON標準で指定されていないため、挿入の順序は重要ではない可能性があります。ただし、キー値は多くの場合、連想配列の内部ソート順または照合に基づいて挿入されます。
連想配列にはvarchar2
キーがあるため、JSONオブジェクトに挿入されるキー・タイプはJSON文字列です。連想配列内のキーの場合、JSONオブジェクトへのコピーに保持されます。
連想配列要素の値は、キーの後にJSONオブジェクトにコピーされます。連想配列の要素タイプがネストした集計タイプである場合、集計タイプに一致するJSONオブジェクトまたは配列がJSON値として作成されます。
例4-13 連想配列からJSONオブジェクトへの変換
この例では、JSONコンストラクタを使用して、連想配列をJSONオブジェクトに変換します。
DECLARE
TYPE AsscArray IS TABLE OF VARCHAR2(10) INDEX BY VARCHAR2(10);
myAsscArray AsscArray := AsscArray('FIRST_NAME' => 'Bob', 'LAST_NAME' => 'Jones');
myJson JSON;
BEGIN
myJson := JSON(myAsscArray);
DBMS_OUTPUT.PUT_LINE(JSON_SERIALIZE(myJson));
END;
/
このPL/SQLブロックを実行すると、次の値を持つJSONオブジェクトが作成されます。
{"FIRST_NAME":"Bob", "LAST_NAME":"Jones"}
VECTORデータ型
ベクトル値は、NULL以外の数値の配列で、すべて同じ数値型です。PL/SQLのベクトルには2つの記憶域属性があります。ベクトルを構成する値の数はそのディメンションで、値の数値型はその書式です。
PL/SQLのベクトル変数はベクトル値を保持し、ディメンション、ディメンション形式および格納形式に関して柔軟性があるか、部分的に柔軟性があるか、完全に柔軟性がありません。柔軟なPL/SQLベクトル変数へのベクトル値の割当ては常に成功し、変換は行われません。値と変数が柔軟性のない属性で異なる場合、代入時にエラーが発生します。すべての場合に、ベクトルに格納される要素は同じ数値型である必要があります。
指定する場合、ベクトルの形式は次のいずれかである必要があります: FLOAT64
、FLOAT32
、INT8
またはBINARY
。BINARY
ベクトルのディメンションは8の倍数である必要があります。BINARY
ベクトルの使用の詳細は、Oracle Database AI Vector Searchユーザーズ・ガイドを参照してください。
ベクトル宣言には、オプションでSPARSE
またはDENSE
のいずれかの格納形式属性を含めることができます。指定しない場合、ベクトルはデフォルトでDENSE
になります。
疎ベクトルは、ディメンション値の大部分がゼロであるベクトルです。ほとんどのディメンション値がゼロになると想定される場合に疎ベクトルを使用すると、ゼロ以外の索引値のみが格納されるため、記憶域を節約できます。SPARSE
ベクトルの文字列表現は、ディメンション値、ゼロ以外のディメンション値を表す索引(非負の整数)のJSON配列、およびそれらのゼロ以外の値のJSON配列の3つの部分で構成されるJSON配列です。たとえば、次の疎表現では、4番目と6番目のディメンションで値が8および24の128個のディメンションのベクトルを示します。他のすべてのディメンション値はゼロと見なされます。
[128, [4, 6], [8, 24]]
SPARSE
ベクトルの詳細は、Oracle Database AI Vector Search ユーザーズ・ガイドを参照してください。
ノート:
ディメンション、ディメンション形式および格納形式のチェックは実行時に完了します。PL/SQLのVECTOR
データ型は、独自のスカラー型ファミリとして示され、PL/SQL演算子で使用したり、PL/SQLプロシージャおよび関数に渡したり、NULL
に設定したり、PL/SQLの他のデータ型と同じ方法で使用できます。ベクトル変数はNULL
ベクトルを保持できますが、ベクトルの値をNULL
にすることはできません。
PL/SQLでの代入のセマンティクスおよび暗黙的な変換の処理は、SQLと異なります。SQLでは次元が完全一致することのみが求められますが、PL/SQLでは正常な代入のためには形式と次元の両方が一致することが求められます。また、SQLではVECTOR
と文字列型の暗黙的な変換が許可されますが、PL/SQLではベクトルと他の型の暗黙的な変換はサポートされません。SQLおよびPL/SQLでは、ベクトルの等価比較はサポートされません。
変数がベクトル変数またはベクトル列で%TYPE
を使用して宣言されている場合、宣言された変数は、参照されるベクトル変数または列の格納属性を継承したベクトルになります。次の例は、この概念を示しています。
CREATE TABLE PLS_VEC_TAB(
v1 vector,
v2 vector(100),
v3 vector(*, INT8),
v4 vector(100, INT8),
v5 vector(1024, BINARY),
v6 vector(100, FLOAT32, DENSE),
v7 vector(100, FLOAT32, SPARSE)
);
DECLARE
vec0 vector; -- dimension and format are flexible, storage format is DENSE
vec1 PLS_VEC_TAB.v1%TYPE; -- dimension and format are flexible, storage format is DENSE
vec2 PLS_VEC_TAB.v2%TYPE; -- dimension is 100, format is flexible, storage format is DENSE
vec3 PLS_VEC_TAB.v3%TYPE; -- dimension is flexible, format is INT8, storage format is DENSE
vec4 PLS_VEC_TAB.v4%TYPE; -- dimension is 100, format is INT8, storage format is DENSE
vec5 PLS_VEC_TAB.v5%TYPE; -- dimension is 1024, format is BINARY, storage format is DENSE
vec6 PLS_VEC_TAB.v6%TYPE; -- dimension is 100, format is FLOAT32, storage format is DENSE
vec7 PLS_VEC_TAB.v7%TYPE; -- dimension is 100, format is FLOAT32, storage format is SPARSE
vec_0 vec0%TYPE; -- dimension and format are flexible, storage format is DENSE
vec_1 vec1%TYPE; -- dimension and format are flexible, storage format is DENSE
vec_2 vec2%TYPE; -- dimension is 100, format is flexible, storage format is DENSE
vec_3 vec3%TYPE; -- dimension is flexible, format is INT8, storage format is DENSE
vec_4 vec4%TYPE; -- dimension is 100, format is INT8, storage format is DENSE
vec_5 vec5%TYPE; -- dimension is 1024, format is BINARY, storage format is DENSE
vec_6 vec6%TYPE; -- dimension is 100, format is FLOAT32, storage format is DENSE
vec_7 vec7%TYPE; -- dimension is 100, format is FLOAT32, storage format is SPARSE
BEGIN
NULL;
END;
/
VECTOR
データ型とそのインスタンスは、次のようなSQLデータ型が使用可能なほとんどの場所で使用できます:
- レコード内の要素またはフィールド・タイプ、PL/SQLコレクションおよび
%ROWTYPE
属性として%ROWTYPE
属性は、基礎となるベクトル列のディメンションと形式の両方を継承することに注意してください。 - 疑似レコード
OLD
およびNEW
を含むPL/SQLトリガー、および条件付きトリガーのWHEN
句。 USING
句では、3つのバインド方向すべて(IN
、IN OUT
およびOUT
)のベクトルがサポートされます。FORALL
句、RETURNING INTO
句およびBULK COLLECT INTO
句。- 加算、減算または乗算の引数として。
VECTOR
データ型は、現在SQLコレクションまたはオブジェクトではサポートされていません。
VECTOR
型の変数は、静的SQL、動的SQLの形式で使用するか、DBMS_SQL
を使用できます。これらのすべての場合に、ベクトルは列の型、バインドの型またはその両方として使用できます。列とバインドの型のいずれかがVECTOR
ではない場合、そうでない方は文字列型である必要があります。VECTOR
データ型を正式な引数として使用するPL/SQLファンクションは、現在、SQL SELECT
文のWITH
句ではサポートされません。
PL/SQLでは、最も内側のスコープに現れる識別子VECTOR
の定義が使用されます。ユーザー定義型がVECTOR
という名前で作成され、名前接頭辞なしで参照される場合、PL/SQLはローカル定義を使用して変数を解釈します。ローカル定義が存在しない場合、PL/SQLでは、名前が解決されるまで検索を外側のスコープに広げていきます(最終的にはパッケージのSTANDARD定義まで)。
ここでのトピック
関連項目:
- Oracle AI Vector Searchの詳細は、『Oracle Database AI Vector Searchユーザーズ・ガイド』を参照してください
VECTOR
データ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
PL/SQLでサポートされているVECTOR操作
PL/SQLでは、VECTOR
データ型で使用する次の基本操作がネイティブにサポートされます。
VECTOR
TO_VECTOR
FROM_VECTOR
(およびVECTOR_SERIALIZE
)脚注4TO_CHAR
TO_CLOB
VECTOR_DIMENSION_COUNT
(およびVECTOR_DIMS
)VECTOR_DIMENSION_FORMAT
VECTOR_NORM
VECTOR_DISTANCE
は、次のメトリック・オプションでサポートされています(メトリックが指定されていない場合、コサイン距離がデフォルトです)。COSINE
MANHATTAN
EUCLIDEAN
EUCLIDEAN_SQUARED
DOT
HAMMING
JACCARD
- 次のベクトル距離関数は、PL/SQLのスタンドアロン関数としてもネイティブにサポートされています。
COSINE_DISTANCE
L1_DISTANCE
(マンハッタン距離)L2_DISTANCE
(ユークリッド距離)INNER_PRODUCT
- さらに、対応するベクトル距離には次の短縮距離演算子を使用できます。
- コサイン距離:
<=>
- ユークリッド距離:
<->
- ドット積:
<#>
- コサイン距離:
対応するベクトル距離メトリック、スタンドアロン・ファンクションおよび短縮距離演算子は、同等の結果になります。たとえば、VECTOR_DISTANCE(v1, v2, COSINE)
はCOSINE_DISTANCE(v1, v2)
と等しく、v1 <=> v2
と等しくなります。
PL/SQLでベクトルを作成するには、VECTOR
またはTO_VECTOR
を使用します。たとえば、次の変数の代入を見てください。
v VECTOR := VECTOR('[1, 2, 3]');
v VECTOR := TO_VECTOR('[1, 2, 3]');
変換が失敗した場合にデフォルト値を決定するために、明示的な変換のSQLで使用されるON CONVERSION ERROR
句は、PL/SQLでサポートされません。かわりに、例外ハンドラのコード・ブロックを使用してデフォルト値を設定できます。
PL/SQLでメトリック・キーワードをネイティブに使用してVECTOR_DISTANCE
関数を使用するか、前にリストした距離関数を使用するか、静的SQLからVECTOR_DISTANCE
をコールできます。この距離は、BINARY_DOUBLE
として返されます。次に、有効な代入を示します。
dist := COSINE_DISTANCE(v1, v2);
dist := VECTOR_DISTANCE(v1, v2, COSINE);
dist := v1 <=> v2;
SELECT VECTOR_DISTANCE(v1, v2, COSINE) INTO dist;
SELECT v1 <=> v2 INTO dist;
加算、減算および乗算の算術演算子は、ベクトルのディメンション単位に適用できます。演算の両側は、ディメンションが一致するベクトルに評価される必要があり、BINARY
またはSPARSE
ベクトルにできません。結果のベクトルは、オペランドと同じ数のディメンションを持ち、形式は入力の形式に基づいて決定されます。演算の片側がベクトルでない場合は、値をベクトルに変換する試みが自動的に行われます。変換に失敗すると、エラーが発生します。
結果に使用される形式は、次の順にランク付けされます: 柔軟、FLOAT64
、FLOAT32
、INT8
。たとえば、演算のいずれかの側に柔軟な形式がある場合、結果は柔軟になります。それ以外の場合、いずれかの側がFLOAT64
という形式の場合は、結果がFLOAT64
のようになります。
算術演算子の構文は次のとおりです:
- 加算:
expr1 + expr2
- 減算:
expr1 - expr2
- 乗算:
expr1 * expr2
算術演算のいずれかの側がNULL
の場合、結果はNULL
になります。ディメンション・オーバーフローの場合、エラーが発生します。たとえば、VECTOR('[1, 127]', 2, INT8)
をVECTOR('[1, 1]', 2, INT8)
に追加すると、127+1=128
がINT8
形式をオーバーフローするため、エラーが発生します。
関連項目:
- ベクトルSQLファンクションの構文およびセマンティクスの詳細は、『Oracle Database SQL言語リファレンス』を参照してください
- ベクトルを使用した算術演算の実行の詳細は、Oracle Database AI Vector Searchユーザーズ・ガイドを参照してください
VECTORデータ型のPL/SQLコードの例
ここに示すPL/SQLコードの例は、VECTOR
データ型の使用方法を示しています。
例4-14 PL/SQLでのVECTORデータ型の使用
この例の最初の部分では、ベクトルを選択してPL/SQLのベクトル変数に代入する方法を示しています。この場合、ベクトル列に%TYPE
を使用しています。
DROP TABLE theVectorTable;
CREATE TABLE theVectorTable (embedding VECTOR(3, float32), id NUMBER);
INSERT INTO theVectorTable VALUES ('[1.11, 2.22, 3.33]', 1);
INSERT INTO theVectorTable VALUES ('[4.44, 5.55, 6.66]', 2);
INSERT INTO theVectorTable VALUES ('[7.77, 8.88, 9.99]', 3);
SET SERVEROUTPUT ON;
DECLARE
v_embedding theVectorTable.embedding%TYPE;
BEGIN
SELECT embedding INTO v_embedding FROM theVectorTable WHERE id=3;
DBMS_OUTPUT.PUT_LINE('Embedding is ' || FROM_VECTOR(v_embedding));
END;
/
結果:
Embedding is [7.76999998E+000,8.88000011E+000,9.98999977E+000]
次の無名ブロックは、バルク・フェッチを行うカーソルを使用して、theVectorTable
のベクトルおよびIDデータをtable%ROWTYPE
索引表に取得します。
DECLARE
TYPE vecTabT IS TABLE OF theVectorTable%ROWTYPE INDEX BY BINARY_INTEGER;
v_vecTabT vecTabT;
CURSOR c IS SELECT * FROM theVectorTable;
BEGIN
OPEN c;
FETCH c BULK COLLECT INTO v_vecTabT;
CLOSE c;
-- display the contents of the vector index table
FOR i IN 1..v_vecTabT.LAST LOOP
DBMS_OUTPUT.PUT_LINE('Embedding ID ' || v_vecTabT(i).id || ': ' ||
FROM_VECTOR(v_vecTabT(i).embedding));
END LOOP;
END;
/
結果:
Embedding ID 1: [1.11000001E+000,2.22000003E+000,3.32999992E+000]
Embedding ID 2: [4.44000006E+000,5.55000019E+000,6.65999985E+000]
Embedding ID 3: [7.76999998E+000,8.88000011E+000,9.98999977E+000]
例4-15 PL/SQLトリガーでのVECTORデータ型の使用
この例では、vecLogTable
にベクトル値を挿入するtheVectorTable
にBEFORE UPDATE
トリガーを作成します。
DROP TABLE vecLogTable;
DROP SEQUENCE vecTrgSeq;
CREATE TABLE vecLogTable (embedding VECTOR(3, float32),
describe VARCHAR2(25), seq NUMBER);
CREATE SEQUENCE vecTrgSeq;
CREATE OR REPLACE TRIGGER vecTrg
BEFORE UPDATE ON theVectorTable
FOR EACH ROW
BEGIN
INSERT INTO vecLogTable VALUES (:old.embedding, 'OLD.VECTRG',
vecTrgSeq.NEXTVAL);
INSERT INTO vecLogTable VALUES (:new.embedding, 'NEW.VECTRG',
vecTrgSeq.NEXTVAL);
END;
/
UPDATE theVectorTable SET embedding='[2.22, 4.44, 6.66]' WHERE id=2;
SELECT * FROM vecLogTable ORDER BY seq;
結果:
EMBEDDING DESCRIBE SEQ
-------------------------------------------------- ---------------- ---
[4.44000006E+000,5.55000019E+000,6.65999985E+000] OLD.VECTRG 1
[2.22000003E+000,4.44000006E+000,6.65999985E+000] NEW.VECTRG 2
例4-16 PL/SQLでのベクトル距離関数の使用
この例は、ベクトル距離関数のPL/SQLサポートを示しています。
DECLARE
v1 VECTOR := TO_VECTOR('[1, 2, 3]');
v2 VECTOR := TO_VECTOR('[4, 5, 6]');
v3 VECTOR := TO_VECTOR('[1, 2, 0, 6]', *, BINARY);
v4 VECTOR := TO_VECTOR('[0, 6, 0, 3]', *, BINARY);
man_dist NUMBER;
euc_dist NUMBER;
cos_dist NUMBER;
inn_dist NUMBER;
ham_dist NUMBER;
dot_dist NUMBER;
jac_dist NUMBER;
BEGIN
man_dist := L1_DISTANCE(v1, v2); --Manhattan Distance
euc_dist := L2_DISTANCE(v1, v2); --Euclidean Distance
cos_dist := COSINE_DISTANCE(v1, v2); --Cosine Distance
inn_dist := INNER_PRODUCT(v1, v2); --Inner Product
--The Hamming Distance has no standalone function in PL/SQL
ham_dist := VECTOR_DISTANCE(v1, v2, HAMMING);
--The Negative Inner (Dot) Product has no standalone function in PL/SQL
dot_dist := VECTOR_DISTANCE(v1, v2, DOT);
--The Jaccard Distance has no standalone function in PL/SQL
jac_dist := VECTOR_DISTANCE(v3, v4, JACCARD);
DBMS_OUTPUT.PUT_LINE('The Manhattan distance is: ' || man_dist);
DBMS_OUTPUT.PUT_LINE('The Euclidean distance is: ' || euc_dist);
DBMS_OUTPUT.PUT_LINE('The Cosine distance is: ' || cos_dist);
DBMS_OUTPUT.PUT_LINE('The Inner Product is: ' || inn_dist);
DBMS_OUTPUT.PUT_LINE('The Hamming distance is: ' || ham_dist);
DBMS_OUTPUT.PUT_LINE('The Dot Product is: ' || dot_dist);
DBMS_OUTPUT.PUT_LINE('The Jaccard Distance between the BINARY vectors v3 and v4 is: ' || jac_dist);
END;
/
結果:
The Manhattan distance is: 9
The Euclidean distance is: 5.1961524227066329
The Cosine distance is: .025368153802923787
The Inner Product is: 32
The Hamming distance is: 3
The Dot Product is: -32
The Jaccard Distance between the BINARY vectors v3 and v4 is: .66666666666666674
例4-17短縮距離演算子の使用
PL/SQLではベクトルを使用した暗黙的な変換がサポートされていないため、変数代入の前または同じ行にベクトルを作成する必要があります。これは、PL/SQLの他の距離関数と同じ動作です。
DECLARE
v1 VECTOR := VECTOR('[1, 2, 3]');
v2 VECTOR := VECTOR('[4, 5, 6]');
cos_dist BINARY_DOUBLE;
euc_dist BINARY_DOUBLE;
dot_dist BINARY_DOUBLE;
BEGIN
cos_dist := v1 <=> v2;
euc_dist := v1 <-> v2;
dot_dist := v1 <#> v2;
DBMS_OUTPUT.PUT_LINE(cos_dist);
DBMS_OUTPUT.PUT_LINE(euc_dist);
DBMS_OUTPUT.PUT_LINE(dot_dist);
END;
/
結果:
2.5368153802923787E-002
5.1961524227066329E+000
-3.2E+001
例4-18 ベクトルに対する算術演算の実行
DECLARE
v1 VECTOR := VECTOR('[10, 20, 30]', 3, INT8);
v2 VECTOR := VECTOR('[6, 4, 2]', 3, INT8);
BEGIN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(v1 + v2));
DBMS_OUTPUT.PUT_LINE(TO_CHAR(v1 - v2));
DBMS_OUTPUT.PUT_LINE(TO_CHAR(v1 * v2));
END;
/
結果:
[16,24,32]
[4,16,28]
[60,80,60]
例4-19 PL/SQLでのDENSEおよびSPARSEベクトルの宣言
DECLARE
vs1 VECTOR(*, *, SPARSE) := VECTOR('[10, [0, 3, 4, 6, 7], [1.9, 4, 7.2, 30, 60]]', *, *, SPARSE);
vs2 VECTOR(*, *, SPARSE) := VECTOR('[10, [1, 3, 4, 8, 9], [4.5, 7.6, 4, 8.1, 5]]', *, *, SPARSE);
vd1 VECTOR(*, *, DENSE) := VECTOR('[1.9, 0, 0, 4, 7.2, 0, 30, 60, 0, 0]', *, *, DENSE);
vd2 VECTOR(*, *, DENSE) := VECTOR('[0, 4.5, 0, 7.6, 4, 0, 0, 0, 8.1, 5]', *, *, DENSE);
BEGIN
DBMS_OUTPUT.PUT_LINE('Vector Distance Sparse: ' || TRUNC(VECTOR_DISTANCE(vs1, vs2), 5));
DBMS_OUTPUT.PUT_LINE('Vector Distance Dense: ' || TRUNC(VECTOR_DISTANCE(vd1, vd2), 5));
END;
/
結果:
Vector Distance Sparse: .93556
Vector Distance Dense: .93556
CHARおよびVARCHAR2変数
長すぎる値の代入または挿入
文字変数に変数の最大サイズより長い値を代入すると、エラーが発生します。たとえば:
DECLARE c VARCHAR2(3 CHAR); BEGIN c := 'abc '; END; /
結果:
DECLARE * ERROR at line 1: ORA-06502: PL/SQL: value or conversion error: character string buffer too small ORA-06512: at line 4
同様に、列に挿入した文字変数の値が、定義されている列幅より長い場合も、エラーが発生します。たとえば:
DROP TABLE t; CREATE TABLE t (c CHAR(3 CHAR)); DECLARE s VARCHAR2(5 CHAR) := 'abc '; BEGIN INSERT INTO t(c) VALUES(s); END; /
結果:
BEGIN * ERROR at line 1: ORA-12899: value too large for column "HR"."T"."C" (actual: 5, maximum: 3) ORA-06512: at line 4
文字値を変数に代入したり、列に挿入する前に、その文字値から後続する空白を削除するには、RTRIM
ファンクション(『Oracle Database SQL言語リファレンス』を参照)を使用します。たとえば:
DECLARE c VARCHAR2(3 CHAR); BEGIN c := RTRIM('abc '); INSERT INTO t(c) VALUES(RTRIM('abc ')); END; /
結果:
PL/SQL procedure successfully completed.
マルチバイト文字の変数の宣言
CHAR
またはVARCHAR2
変数の最大サイズは、最大サイズを文字数で指定するかバイト数で指定するかに関係なく、32,767バイトです。変数の最大文字数は、文字セットのタイプによって、場合によっては文字自体によって異なります。
文字セットのタイプ | 最大文字数 |
---|---|
シングルバイト文字セット |
32,767 |
nバイトの固定幅マルチバイト文字セット(AL16UTF16など) |
|
文字幅が1とnバイトの間である、nバイトの可変幅マルチバイト文字セット(JA16SJISやAL32UTF8など) |
文字自体によって異なり、32,767(1バイト文字のみを含む文字列の場合)から |
任意のマルチバイト文字セットでn個の文字を常に保持できるように、CHAR
またはVARCHAR2
変数を宣言する場合は、CHAR(
n
CHAR)
またはVARCHAR2(
n
CHAR)
を使用して、文字数の長さを宣言します(nはFLOOR(32767/4)
= 8191を超えることはできません)。
関連項目:
Oracle Databaseの文字セットのサポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。
CHARとVARCHAR2のデータ型の違い
CHAR
とVARCHAR2
のデータ型は、次の点で異なっています。
事前定義のサブタイプ
CHAR
データ型には、PL/SQLとSQLの両方にCHARACTER
というサブタイプが1つ事前定義されています。
VARCHAR2
データ型には、PL/SQLとSQLの両方にVARCHAR
というサブタイプが1つ事前定義されており、PL/SQLには、STRING
というサブタイプがもう1つ事前定義されています。
各サブタイプの値の範囲はそのベース型と同じです。
ノート:
PL/SQLの今後のリリースでのVARCHAR
は、新しいSQL標準に従うために別のデータ型になり、VARCHAR2
と同義ではなくなる可能性があります。
空白埋めの動作方法
これは、空白埋めを使用する場合のCHARとVARCHAR2での相違点および考慮事項を説明しています。
次の状況について考えてみます:
-
変数に代入した値がこの変数の最大サイズより短い。
-
列に挿入した値が、定義されている列幅より短い。
-
列から取り出して変数に入れた値が、この変数の最大サイズより短い。
受信者のデータ型がCHAR
の場合、PL/SQLは最大サイズになるまで値を空白で埋めます。元の値の後続する空白に関する情報は失われます。
受信者のデータ型がVARCHAR2
の場合、PL/SQLは値の空白埋めも、後続する空白の削除もしません。文字値はそのまま代入され、情報は失われません。
例4-20 CHARおよびVARCHAR2の空白埋めの相違点
この例では、CHAR
変数とVARCHAR2
変数は、どちらも最大サイズが10文字です。それぞれの変数に、1つの空白が後続している5文字の値を代入します。CHAR
変数に代入した値は空白が埋められて10文字になり、結果の値に含まれる後続の空白6つのうち、1つは元の値に含まれていたものだとは見分けられません。VARCHAR2
変数に代入された値は変化しないため、後続の空白が1つあることを確認できます。
DECLARE first_name CHAR(10 CHAR); last_name VARCHAR2(10 CHAR); BEGIN first_name := 'John '; last_name := 'Chen '; DBMS_OUTPUT.PUT_LINE('*' || first_name || '*'); DBMS_OUTPUT.PUT_LINE('*' || last_name || '*'); END; /
結果:
*John * *Chen *
値の比較
SQLの文字値の比較ルールが、PL/SQLの文字変数に適用されます。
比較する値の1つまたは両方のデータ型がVARCHAR2
またはNVARCHAR2
の場合は、非空白埋め比較セマンティクスが適用されますが、それ以外の場合は、空白埋めセマンティクスが適用されます。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
LONGおよびLONG RAW変数
ノート:
Oracleは、既存アプリケーションとの下位互換性のためにのみ、LONG
およびLONG
RAW
データ型をサポートしています。新しいアプリケーションでは次のようにしてください:
-
LONG
のかわりに、VARCHAR2(32760)
、BLOB
、CLOB
またはNCLOB
を使用する。 -
LONG
RAW
のかわりに、RAW(32760)
またはBLOB
を使用する。
LONG
データ型からLOB
データ型に列を移行する方法の詳細は、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイドを参照してください。
LONG
列には、任意のLONG
値を挿入できます。LONG
RAW
列には、任意のLONG
RAW
値を挿入できます。LONG
またはLONG
RAW
列からは、32760バイトを超える長さの値を取り出して、LONG
またはLONG
RAW
変数に入れることはできません。
LONG
列には、任意のCHAR
またはVARCHAR2
値を挿入できます。LONG
列からは、32,767バイトを超える長さの値を取り出してCHAR
変数またはVARCHAR2
変数に入れることはできません。
LONG
RAW
列には、任意のRAW
値を挿入できます。LONG
RAW
列からは、32767バイトを超える長さの値を取り出してRAW
変数に入れることはできません。
関連項目:
トリガー内のLONG
データ型およびLONG
RAW
データ型の制約については、「トリガーのLONGおよびLONG RAWデータ型の制約」を参照してください
ROWIDおよびUROWID変数
ROWIDを取り出してROWID
変数に入れる場合は、バイナリ値を文字値に変換するROWIDTOCHAR
ファンクションを使用します。このファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
ROWID
変数の値をROWIDに変換するには、CHARTOROWID
ファンクション(『Oracle Database SQL言語リファレンス』を参照)を使用します。値が有効なROWIDを表していない場合は、PL/SQLにより事前定義の例外SYS_INVALID_ROWID
が呼び出されます。
ROWIDを取り出してUROWID
変数に入れる場合、またはUROWID
変数の値をROWIDに変換する場合は、代入文を使用します。変換は暗黙的に実行されます。
ノート:
-
UROWID
は論理ROWIDと物理ROWIDの両方と互換性があるため、ROWID
より汎用性の高いデータ型です。 -
ハイブリッド列圧縮(HCC)で圧縮された表の行を更新すると、行の
ROWID
が変更されます。特定のOracleストレージ・システムの機能であるHCCの詳細は、『Oracle Database概要』を参照してください。
脚注の説明
脚注4: オプションのRETURNING
句は、TO_VECTOR
およびVECTOR_SERIALIZE
ではサポートされていません。