Oracleデータベース
CREATE PROCEDURE search_test(h_where CLOB) AS
str_sql CLOB;
v_cnt INTEGER;
v_array DBMS_SQL.VARCHAR2A;
v_cur INTEGER;
v_smpid INTEGER;
v_smpnm VARCHAR2(20);
v_addbuff VARCHAR2(20);
v_smpage INTEGER;
errcd INTEGER;
length INTEGER;
ret INTEGER;
BEGIN
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;・・・(1)
v_cnt :=
CEIL(DBMS_LOB.GETLENGTH(str_sql)/1000);
FOR idx IN 1 .. v_cnt LOOP
v_array(idx) :=
DBMS_LOB.SUBSTR(str_sql,
1000,
(idx-1)*1000+1);
END LOOP;
DBMS_SQL.PARSE(v_cur, v_array, 1, v_cnt, FALSE, DBMS_SQL.NATIVE);・・・(2)
DBMS_SQL.DEFINE_COLUMN(v_cur, 1, v_smpid);
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;
DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
DBMS_SQL.COLUMN_VALUE(v_cur, 1, v_smpid, errcd, length);・・・(3)
IF errcd = 1405 THEN・・・(3)
DBMS_OUTPUT.PUT_LINE('smpid = (NULL)');
ELSE
DBMS_OUTPUT.PUT_LINE('smpid = ' || v_smpid);
END IF;
DBMS_SQL.COLUMN_VALUE(v_cur, 2, v_smpnm, errcd, length);
IF errcd = 1406 THEN
v_addbuff := '... [len=' || length || ']';
END IF;
IF errcd = 1405 THEN
DBMS_OUTPUT.PUT_LINE('v_smpnm = (NULL)');
ELSE
DBMS_OUTPUT.PUT_LINE('v_smpnm = ' || v_smpnm || v_addbuff );
END IF;
DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------');
DBMS_OUTPUT.NEW_LINE;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(v_cur);・・・(4)
RETURN;
END;
/
Set serveroutput on
call search_test('smpid < 100');FUJITSU Enterprise Postgres
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();・・・(1)
PERFORM DBMS_SQL.PARSE(v_cur, str_sql, 1);・・・(2)
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);・・・(3)
IF errcd = 22002 THEN・・・(3)
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);・・・(4)
RETURN;
END;
$$
LANGUAGE plpgsql;
SELECT search_test('smpid < 100');DBMS_OUTPUTパッケージのNEW_LINEと同じです。記述差異および、記述差異に伴う移行手順については、DBMS_OUTPUTパッケージのNEW_LINEを参照してください。
DBMS_SQL.PARSE(第1引数, 第2引数, 第3引数, 第4引数, 第5引数, 第6引数)
SQL文を文字列の表タイプ(VARCHAR2A型、VARCHAR2S型)で指定することができます。これは、第2引数に指定します。
SQL文を処理する方法の指定にDBMS_SQL.NATIVE、DBMS_SQL.V6、DBMS_SQL.V7を指定することができます。
SQL文を文字列の表タイプでは指定できません。
SQL文を処理する方法の指定にDBMS_SQL.NATIVE、DBMS_SQL.V6、DBMS_SQL.V7を指定することができません。
以下の手順で移行してください。
“DBMS_SQL.PARSE”というキーワードでストアドプロシジャ内を検索し、呼び出し箇所を特定します。
第2引数(例のv_array)に指定されたSQL文のデータ型を確認します。
データ型がDBMS_SQL.VARCHAR2A型、またはDBMS_SQL.VARCHAR2S型である場合は、表タイプによる指定です。3.の手順から移行処理を継続してください。
データ型がDBMS_SQL.VARCHAR2A型、またはDBMS_SQL.VARCHAR2S型でない場合は、文字列による指定です。7.の手順から移行処理を継続してください。
DBMS_SQL.VARCHAR2A型、およびDBMS_SQL.VARCHAR2S型に分割する前のSQL文(例のstr_sql)を確認します。
DBMS_SQL.VARCHAR2A型、およびDBMS_SQL.VARCHAR2S型にSQLを分割している一連の処理(例のFOR idx付近の処理)を削除します。
第2引数を2.で確認した分割する前のSQL文(例のstr_sql)に置き換えます。
第3引数~第5引数(例のv_cnt, FALSE, DBMS_SQL.NATIVE)までを削除します。
DBMS_SQL.NATIVE、DBMS_SQL.V6、DBMS_SQL.V7が指定されている場合は、第3引数を数定数 1 に置き換えます。
DBMS_SQL.VARCHAR2A型、またはDBMS_SQL.VARCHAR2S型を使用している場合は第6引数が該当します。
DBMS_SQL.VARCHAR2A型、またはDBMS_SQL.VARCHAR2S型を使用していない場合は第3引数が該当します。
DBMS_SQL.COLUMN_VALUE(第1引数, 第2引数, 第3引数, 第4引数, 第5引数)
column_errorに対して以下のエラーコードを戻します。
1406 : 取得した値が切り捨てられている
1405 : 取得した値の内容がNULL値
column_errorに対して以下のエラーコードを戻します。
22001 : 取得した値が切り捨てられている
22002 : 取得した値の内容がNULL値
取得する値は、引数に指定した変数で受け取ります。
取得する値は、DBMS_SQL.COLUMN_VALUEの検索結果なので、SELECT文のINTO句に指定した変数で受け取ります。
以下の手順で移行してください。
“DBMS_SQL.COLUMN_VALUE”というキーワードでストアドプロシジャ内を検索し、呼び出し箇所を特定します。
DBMS_SQL.COLUMN_VALUEの呼び出し箇所を、SELECT INTO文に置き換えます。
DBMS_SQL.COLUMN_VALUEの第3引数(例のv_smpid)以降に指定している引数の数を確認します(例の場合は、v_smpid, errcd, length の3個)。
選択リストに、先で確認した引数の数に応じてそれぞれvalue、column_error、actual_lengthの順で指定します。(例えば、第3引数のみ指定されている場合はvalueのみを指定します)
INTO句に、DBMS_SQL.COLUMN_VALUEに設定していた第3引数~第5引数(例のv_smpid, errcd, length)を同じ順番で指定します。
FROM句にDBMS_SQL.COLUMN_VALUEを記載します。引数は修正前の第1引数~第3引数(例のv_cur, 1, v_smpid)までを指定します。
第4引数(例のcolumn_errorの値)を使用している場合は、対象の変数(例のerrcd)を使用している箇所を確認します。
確認した箇所で判定などの処理を行っている場合は、判定する際の値を以下の通り修正します。
1406 ⇒ 22001
1405 ⇒ 22002
DBMS_SQL.CLOSE_CURSOR(第1引数)
クローズすると、引数に指定したカーソルがNULL値になります。
クローズすると、DBMS_SQL.CLOSE_CURSORの復帰値がNULL値になりますので、代入文に指定したカーソルで受け取ります。
以下の手順で移行してください。
“DBMS_SQL.CLOSE_CURSOR”というキーワードでストアドプロシジャ内を検索し、呼び出し箇所を特定します。
DBMS_SQL.CLOSE_CURSORの呼び出し箇所を、値の代入(:=)に置き換え、カーソルがNULL値となるようにします。
左辺にDBMS_SQL.CLOSE_CURSORに指定していた引数(例のv_cur)を指定します。
右辺にDBMS_SQL.CLOSE_CURSORを記載します。引数は修正前と同じ値(例のv_cur)を指定します。