2.3 ストアド・プロシージャおよびストアド・ファンクションの実行
プロシージャ機能を使用すると、ゲートウェイはSybaseデータベースで定義されたストアド・プロシージャを実行できます。 ゲートウェイを再リンクしたり、プロシージャをゲートウェイに定義する必要はありませんが、プロシージャのアクセス権限はゲートウェイによるアクセスを許可する必要があります。
Standard PL/SQL文は、ストアド・プロシージャの実行に使用されます。
ゲートウェイは、相互に排他的な3つのモードでストアド・プロシージャをサポートしています:
-
通常モード:
IN
/OUT
引数にのみアクセスできます -
戻り値モード: すべてのストアド・プロシージャの戻り値があります
-
結果セット・モード: 出力値は、最後の結果セットとして使用できます
- 「戻り値およびストアド・プロシージャ」
デフォルトでは、すべてのストアドプロシージャおよびストアド関数は、ユーザーに戻り値を返しません。 - 「結果セットとストアド・プロシージャ」
Oracle Database Gateway for Sybaseは、結果セットを返すストアド・プロシージャをサポートします。
親トピック: Sybase Gatewayの機能と制限
2.3.1 戻り値およびストアド・プロシージャ
デフォルトでは、すべてのストアド・プロシージャおよび関数は、ユーザーに戻り値を返しません。
戻り値を有効にするには、初期化パラメータ・ファイルでHS_FDS_PROC_IS_FUNC
パラメータを設定します。
関連項目:
初期化パラメータ・ファイルとHS_FDS_PROC_IS_FUNC
パラメータの編集の詳細は、「初期化パラメータ」を参照してください。
ノート:
HS_FDS_PROC_IS_FUNC
ゲートウェイ初期化パラメータを設定する場合は、既存のすべてのストアド・プロシージャのプロシージャ実行文の構文を変更する必要があります。
次の例では、従業員名JOHN SMYTHE
がSybaseストアド・プロシージャREVISE_SALARY
に渡されます。 ストアド・プロシージャは、Sybaseデータベースから給与値を取得し、JOHN SMYTHE
の新しい年次給与を計算します。 RESULT
で戻された改訂済給与は、Oracleデータベースの表でEMP
を更新するために使用されます:
DECLARE INPUT VARCHAR2(15); RESULT NUMBER(8,2); BEGIN INPUT := 'JOHN SMYTHE'; RESULT := REVISE_SALARY@SYBS(INPUT); UPDATE EMP SET SAL = RESULT WHERE ENAME =: INPUT; END; /
プロシージャ機能は、Oracle以外のデータ型をPL/SQLデータ型との間で自動的に変換します。
親トピック: ストアド・プロシージャおよびストアド関数の実行
2.3.2 結果セットとストアド・プロシージャ
Oracle Database Gateway for Sybaseは、結果セットを返すストアド・プロシージャをサポートします。
デフォルトでは、すべてのストアド・プロシージャおよび関数は、ユーザーに結果セットを返しません。 結果セットを有効にするには、初期化パラメータ・ファイルでHS_FDS_RESULTSET_SUPPORT
パラメータを設定します。
関連項目:
初期化パラメータ・ファイルとHS_FDS_RESULTSET_SUPPORT
パラメータの編集の詳細は、「初期化パラメータ」を参照してください。 Oracle以外のデータベースでの結果セットに対するOracleサポートの詳細は、「Oracle Database異機種間接続ユーザー・ガイド」を参照してください。
ノート:
HS_FDS_RESULTSET_SUPPORT
ゲートウェイ初期化パラメータを設定する場合は、既存のすべてのストアド・プロシージャに対してプロシージャ実行文の構文を変更する必要があります。そうしないと、エラーが発生します。
Oracle Database Gateway for Sybaseを介して結果セットを含むストアド・プロシージャにアクセスすると、異機種間サービスの順次モードになります。
Oracle Database Gateway for Sybaseは、プロシージャの説明中に異機種間サービスに次の情報を返します:
- リモート・ストアド・プロシージャのすべての入力引数
- 出力引数はなし
- 参照カーソル・タイプの1つの出力引数(ストアド・プロシージャから戻される最初の結果セットに対応)
クライアント・プログラムは、仮想パッケージ関数dbms_hs_result_set.get_next_result_set
を使用して、後続の結果セットの参照カーソルを取得する必要があります。 最後に返される結果セットは、プロシージャのout引数です。
結果セットへのアクセスの制限は次のとおりです:
- リモート・ストアド・プロシージャから戻された結果セットは、送信された順に取得される必要があります
- ストアド・プロシージャの実行時に、以前に実行されたストアド・プロシージャから戻された結果セットがすべて(データが完全に完了しているかどうかに関係なく)クローズされます
次の例では、Sybaseストアド・プロシージャを実行して、Sybaseからemp
表およびdept
表の内容をフェッチします:
create procedure REFCURPROC (@arg1 varchar(255), @arg2 varchar(255) output) as select @arg2 = @arg1 select * from EMP select * from DEPT go
このストアド・プロシージャは、入力パラメータarg1を出力パラメータarg2に割り当て、参照カーソルrc1で問合せSELECT * FROM EMP
を開き、参照カーソルrc2
で問合せSELECT * FROM DEPT
を開きます。
ノート:
ストアド・プロシージャを作成する前に、チェーン・モードを設定する必要があります。 Sybaseで次のコマンドを発行:set chained on
- 「順次モードでの結果セットからのOCIプログラム・フェッチ」
結果セットから順次モードでフェッチするOCIプログラムの例。 - 「PL/SQL順次モードでの結果セットからのプログラム・フェッチ」
結果セットから順次モードでフェッチするPL/SQLプログラムの例。
親トピック: ストアド・プロシージャおよびストアド関数の実行
2.3.2.1 順次モードでの結果セットからのOCIプログラム・フェッチ
結果セットから順次モードでフェッチするOCIプログラムの例。
次の例は、結果セットから順次モードでフェッチするOCIプログラムを示しています:
OCIEnv *ENVH; OCISvcCtx *SVCH; OCIStmt *STMH; OCIError *ERRH; OCIBind *BNDH[3]; OraText arg1[20]; OraText arg2[255]; OCIResult *rset; OCIStmt *rstmt; ub2 rcode[3]; ub2 rlens[3]; sb2 inds[3]; OraText *stmt = (OraText *) "begin refcurproc@SYBS(:1,:2,:3); end;"; OraText *n_rs_stm = (OraText *) "begin :ret := DBMS_HS_RESULT_SET.GET_NEXT_RESULT_SET@SYBS; end;"; /* Prepare procedure call statement */ /* Handle Initialization code skipped */ OCIStmtPrepare(STMH, ERRH, stmt, strlen(stmt), OCI_NTV_SYNTAX, OCI_DEFAULT); /* Bind procedure arguments */ inds[0] = 0; strcpy((char *) arg1, "Hello World"); rlens[0] = strlen(arg1); OCIBindByPos(STMH, &BNDH[0], ERRH, 1, (dvoid *) arg1, 20, SQLT_CHR, (dvoid *) &(inds[0]), &(rlens[0]), &(rcode[0]), 0, (ub4 *) 0, OCI_DEFAULT); inds[1] = -1; OCIBindByPos(STMH, &BNDH[1], ERRH, 1, (dvoid *) arg2, 20, SQLT_CHR, (dvoid *) &(inds[1]), &(rlens[1]), &(rcode[1]), 0, (ub4 *) 0, OCI_DEFAULT); inds[2] = 0; rlens[2] = 0; OCIDescriptorAlloc(ENVH, (dvoid **) &rset, OCI_DTYPE_RSET, 0, (dvoid **) 0); OCIBindByPos(STMH, &BNDH[2], ERRH, 2, (dvoid *) rset, 0, SQLT_RSET, (dvoid *) &(inds[2]), &(rlens[2]), &(rcode[2]), 0, (ub4 *) 0, OCI_DEFAULT); /* Execute procedure */ OCIStmtExecute(SVCH, STMH, ERRH, 1, 0, (CONST OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DEFAULT); /* Convert result set to statement handle */ OCIResultSetToStmt(rset, ERRH); rstmt = (OCIStmt *) rset; /* After this the user can fetch from rstmt */ /* Issue get_next_result_set call to get handle to next_result set */ /* Prepare Get next result set procedure call */ OCIStmtPrepare(STMH, ERRH, n_rs_stm, strlen(n_rs_stm), OCI_NTV_SYNTAX, OCI_DEFAULT); /* Bind return value */ OCIBindByPos(STMH, &BNDH[1], ERRH, 1, (dvoid *) rset, 0, SQLT_RSET, (dvoid *) &(inds[1]), &(rlens[1]), &(rcode[1]), 0, (ub4 *) 0, OCI_DEFAULT); /* Execute statement to get next result set*/ OCIStmtExecute(SVCH, STMH, ERRH, 1, 0, (CONST OCISnapshot *) 0, (OCISnapshot *) 0, OCI_DEFAULT); /* Convert next result set to statement handle */ OCIResultSetToStmt(rset, ERRH); rstmt = (OCIStmt *) rset; /* Now rstmt will point to the second result set returned by the remote stored procedure */ /* Repeat execution of get_next_result_set to get the output arguments */
親トピック: 結果セットとストアド・プロシージャ
2.3.2.2 PL/SQL順次モードでの結果セットからのプログラム・フェッチ
結果セットから順次モードでフェッチするPL/SQLプログラムの例。
表loc_emp
がSybase emp表とまったく同じローカル表であるとします。 同じ仮定がloc_dept
にも当てはまります。outargs
は、Sybaseストアド・プロシージャのout引数に対応する列を含む表です。
create or replace package rcpackage is type RCTYPE is ref cursor; end rcpackage; /
declare rc1 rcpackage.rctype; rec1 loc_emp%rowtype; rc2 rcpackage.rctype; rec2 loc_dept%rowtype; rc3 rcpackage.rctype; rec3 outargs%rowtype; out_arg varchar2(255); begin -- Execute procedure out_arg := null; refcurproc@SYBS('Hello World', out_arg, rc1); -- Fetch 20 rows from the remote emp table and insert them into loc_emp for i in 1 .. 20 loop fetch rc1 into rec1; insert into loc_emp (rec1.empno, rec1.ename, rec1.job, rec1.mgr, rec1.hiredate, rec1.sal, rec1.comm, rec1.deptno); end loop; -- Close ref cursor close rc1; -- Get the next result set returned by the stored procedure rc2 := dbms_hs_result_set.get_next_result_set@SYBS; -- Fetch 5 rows from the remote dept table and insert them into loc_dept for i in 1 .. 5 loop fetch rc2 into rec2; insert into loc_dept values (rec2.deptno, rec2.dname, rec2.loc); end loop; --Close ref cursor close rc2; -- Get the output arguments from the remote stored procedure -- Since we are in sequential mode, they will be returned in the -- form of a result set rc3 := dbms_hs_result_set.get_next_result_set@SYBS; -- Fetch them and insert them into the outarguments table fetch rc3 into rec3; insert into outargs (rec3.outarg, rec3.retval); -- Close ref cursor close rc3; end; /
親トピック: 結果セットとストアド・プロシージャ