各機能の修正方法を説明します。
なお、文中の<datatatype>は、“G.3 Fujitsu Enterprise Postgres 16 SPz以前のDBMS_SQLパッケージ”に記載されているデータ型を示します。
文内の変数の名前に基づいて、カーソル内の指定の変数に指定の値または値のセットをバインドします。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | integer, text, <datatype> [, integer] |
新パッケージ | プロシージャ | integer, oracle.varchar2, "any" |
関数 |
プロシージャ、関数に応じて実行方法を変更する必要があります。
第4引数を指定している場合は、本機能を使用する前に、第4引数の長さで指定できるように事前に第2引数の文字列をLEFT関数で切り取ってから指定してください。
指定したカーソルをクローズして、メモリを解放します。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | integer |
新パッケージ | プロシージャ | integer |
実行方法をプロシージャに変更する必要があります。
カーソル内の指定位置にあるカーソル要素の値を第三引数に指定した変数に代入します。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | integer, integer, INOUT <datatype> |
新パッケージ | プロシージャ | integer, integer, INOUT anyelement |
関数 |
プロシージャ、関数に応じて実行方法を変更する必要があります。
結果の文字列の長さが必要な場合は、本機能を使用した後、LENGTH関数で長さを取得する処理を追加してください。
処理結果に対するエラーコード(22001、22002)は取得できません。判定しているエラーコードの種類に応じて処理を追加する必要があります。
[エラーコード 22002を判定する必要がある場合]
結果の文字列がNULL値かどうかを判断しています。
新パッケージのCOLUMN_VALUEでは、「エラーコードの22002の判定処理を、結果の文字列のNULL値判定処理に変更する」、または「結果の文字列のNULL値判定を事前に実行し、NULL値の場合はエラーコードの22002に自身で設定する」のいずれかの対応を行ってください。
[エラーコード 22001を判定する必要がある場合]
結果の文字列が、事前にDEFINE_COLUMNで指定した最大文字列長で切り捨てられたかを判断しています。また、最大文字列長は、事前に実行するDEFINE_COLUMNの第4引数の値が使用されます。そのため、新パッケージのCOLUMN_VALUEでエラーコード22001と同じ結果を得るためには、以下の対応が必要になります。
・INTEGER型の変数を別途用意し、DEFINE_COLUMNの第4引数の値はその変数に設定するとともに、第4引数を省略します。
・結果の文字列の長さと退避しておいた最大文字列長を比較し、「結果の文字列の長さの方が大きい場合はエラーコードの22001の判定処理を実行する」、または「エラーコードの22001を自身で設定し、後続のエラーコード判定処理を実行可能にする」のいずれかの対処を行います。
例) 以下はNULL値、および最大文字列長で切り捨てに対する、エラーコード判定処理の対応例です。
max_length INTEGER;
errcd INTEGER;
length INTEGER;
・・・
max_length := 10;
CALL DEFINE_COLUMN(v_cursor, 1, v_string_values1);
・・・
errcd := 0;
length := 0;
CALL COLUMN_VALUE(v_cursor, 1, v_string_values1);
-- errcdの設定
IF v_string_values1 IS NULL THEN
errcd := 22002;
ELSE
IF LENGTH(v_string_values1) > max_length THEN
errcd := 22001;
v_string_values1 := LEFT(v_string_values1, max_length);
END IF;
END IF;
-- lengthの設定
length := LENGTH(v_string_values1);
IF errcd = 22001 THEN
-- errcd 22001の処理
・・・
END IF;
IF errcd = 22002 THEN
-- errcd 22002の処理
・・・
END IF;
指定のカーソルから選択する列を定義します。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | integer, integer, <datatype> [, integer] |
新パッケージ | プロシージャ | integer, integer, "any" [, integer] |
実行方法をプロシージャに変更する必要があります。
第4引数を指定している、かつ、後続のCOLUMN_VALUEで文字列の切り捨て(エラーコード:22001)を判定する処理が行われている場合には、第4引数を指定している数値をINTEGER型の変数に退避し、第4引数は省略に変更してください。COLUMN_VALUEでの対応は “COLUMN_VALUE”を参照してください。
SELECTで指定したすべての列に対して、本機能を実行する必要があります。抜けや漏れがある状態でEXECUTEを実行するとエラーとなります。
一部の列だけをDEFINE_COLUMNで取得できます。
例) 2つ目の列を取得する場合
SQL := 'SELECT id, data, val1 FROM test WHERE data=:x';
perform DBMS_SQL.DEFINE_COLUMN(CURSOR, 2, COL2, 10 );
一部の列だけ必要な場合でもすべての列をDEFINE_COLUMNで取得する必要があります。そのため、以下のいずれかで対応してください。
例1) すべての列に対して、DEFINE_COLUMNを実行します。
SQL := 'SELECT id, data, va1 FROM test WHERE data=:x';
call DBMS_SQL.DEFINE_COLUMN(CURSOR, 1, COL1, 10 );
call DBMS_SQL.DEFINE_COLUMN(CURSOR, 2, COL2, 10 );
call DBMS_SQL.DEFINE_COLUMN(CURSOR, 3, COL3, 10 );
例2) 必要な列だけ取得するように、SELECT文を修正します。
SQL := 'SELECT data FROM test WHERE data=:x';
call DBMS_SQL.DEFINE_COLUMN(CURSOR, 1, COL2, 10 );
指定のカーソルを実行します。
違いはありません。
指定のカーソルから行をフェッチします。
違いはありません。
新規のカーソルをオープンします。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | [integer] |
新パッケージ | 関数 | void |
引数は不要なため、指定している場合は削除してください。
指定したカーソル内の指定した文を解析します。すべての文が即時に解析されます。さらに、DDL文は、解析時にただちに実行されます。
種別 | 引数の型 | |
|---|---|---|
旧パッケージ | 関数 | integer, text [, integer, text DEFAULT '', text DEFAULT '', Boolean DEFAULT false] |
新パッケージ | プロシージャ | integer, oracle.varchar2 |
実行方法をプロシージャに変更する必要があります。
例)旧パッケージでのプログラム例
CREATE FUNCTION search_test(h_where text) RETURNS void AS $$
DECLARE
str_sql text;
v_cur INTEGER;
v_smpid INTEGER;
v_smpnm VARCHAR(20);
v_addbuff VARCHAR(20);
v_smpage INTEGER;
errcd INTEGER;
length INTEGER;
ret INTEGER;
BEGIN
PERFORM DBMS_OUTPUT.SERVEROUTPUT(TRUE);
str_sql := 'SELECT smpid, smpnm FROM smp_tbl WHERE ' || h_where || ' ORDER BY smpid';
v_smpid := 0;
v_smpnm := '';
v_smpage := 0;
v_cur := DBMS_SQL.OPEN_CURSOR();
PERFORM DBMS_SQL.PARSE(v_cur, str_sql, 1);
PERFORM DBMS_SQL.DEFINE_COLUMN(v_cur, 1, v_smpid);
PERFORM DBMS_SQL.DEFINE_COLUMN(v_cur, 2, v_smpnm, 10);
ret := DBMS_SQL.EXECUTE(v_cur);
LOOP
v_addbuff := '';
IF DBMS_SQL.FETCH_ROWS(v_cur) = 0 THEN
EXIT;
END IF;
PERFORM DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
SELECT value,column_error,actual_length
INTO v_smpid, errcd, length
FROM DBMS_SQL.COLUMN_VALUE(v_cur,
1,
v_smpid);
IF errcd = 22002 THEN
PERFORM DBMS_OUTPUT.PUT_LINE('smpid = (NULL)');
ELSE
PERFORM DBMS_OUTPUT.PUT_LINE('smpid = ' || v_smpid);
END IF;
SELECT value,column_error,actual_length INTO v_smpnm, errcd, length FROM DBMS_SQL.COLUMN_VALUE(v_cur, 2, v_smpnm);
IF errcd = 22001 THEN
v_addbuff := '... [len=' || length || ']';
END IF;
IF errcd = 22002 THEN
PERFORM DBMS_OUTPUT.PUT_LINE('v_smpnm = (NULL)');
ELSE
PERFORM DBMS_OUTPUT.PUT_LINE('v_smpnm = ' || v_smpnm || v_addbuff );
END IF;
PERFORM DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
PERFORM DBMS_OUTPUT.NEW_LINE();
END LOOP;
v_cur := DBMS_SQL.CLOSE_CURSOR(v_cur);
RETURN;
END;
$$
LANGUAGE plpgsql;
例) 新パッケージへの移行後の例
赤字が修正箇所になります。
CREATE FUNCTION search_test(h_where text) RETURNS void AS $$
DECLARE
str_sql text;
v_cur INTEGER;
v_smpid INTEGER;
v_smpnm VARCHAR(20);
v_smpnm_max_length INTEGER;
v_addbuff VARCHAR(20);
v_smpage INTEGER;
errcd INTEGER;
length INTEGER;
ret INTEGER;
BEGIN
PERFORM DBMS_OUTPUT.SERVEROUTPUT(TRUE);
str_sql := 'SELECT smpid, smpnm FROM smp_tbl WHERE ' || h_where || ' ORDER BY smpid';
v_smpid := 0;
v_smpnm := '';
v_smpage := 0;
v_cur := DBMS_SQL.OPEN_CURSOR();
CALL DBMS_SQL.PARSE(v_cur, str_sql);
CALL DBMS_SQL.DEFINE_COLUMN(v_cur, 1, v_smpid);
CALL DBMS_SQL.DEFINE_COLUMN(v_cur, 2, v_smpnm);
v_smpnm_max_length := 10;
ret := DBMS_SQL.EXECUTE(v_cur);
LOOP
v_addbuff := '';
IF DBMS_SQL.FETCH_ROWS(v_cur) = 0 THEN
EXIT;
END IF;
PERFORM DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
errcd := 0;
length := 0;
CALL DBMS_SQL.COLUMN_VALUE(v_cur, 1, v_smpid);
IF v_smpid IS NULL THEN
errcd := 22002;
END IF;
IF errcd = 22002 THEN
PERFORM DBMS_OUTPUT.PUT_LINE('smpid = (NULL)');
ELSE
PERFORM DBMS_OUTPUT.PUT_LINE('smpid = ' || v_smpid);
END IF;
CALL DBMS_SQL.COLUMN_VALUE(v_cur, 2, v_smpnm);
errcd := 0;
length := 0;
IF v_smpnm IS NULL THEN
errcd := 22002;
ELSE;
length := LENGTH(v_smpnm);
IF length > v_smpnm_max_length THEN
errcd := 22001;
length := v_smpnm_max_length;
v_smpnm := LEFT(v_smpnm, v_smpnm_max_length);
END IF;
END IF;
IF errcd = 22001 THEN
v_addbuff := '... [len=' || length || ']';
END IF;
IF errcd = 22002 THEN
PERFORM DBMS_OUTPUT.PUT_LINE('v_smpnm = (NULL)');
ELSE
PERFORM DBMS_OUTPUT.PUT_LINE('v_smpnm = ' || v_smpnm || v_addbuff );
END IF;
PERFORM DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
PERFORM DBMS_OUTPUT.NEW_LINE();
END LOOP;
CALL DBMS_SQL.CLOSE_CURSOR(v_cur);
v_cur := NULL;
RETURN;
END;
$$
LANGUAGE plpgsql;