Oracleプリコンパイラでは、ホスト表に対するDB2のINSERTおよびFETCH構文もサポートされています。サポートされている追加の配列の挿入およびフェッチ構文は、次の図にそれぞれ示しています。
オプションでROWSET句とROWSET STARTING AT句がフェッチの方向(FIRST, PRIOR, NEXT, LAST, CURRENT, RELATIVEおよびABSOLUTE)で使用されます。次の例を参考にしてください。
FIRST ROWSET
PRIOR ROWSET
NEXT ROWSET
LAST ROWSET
CURRENT ROWSET
ROWSET STARTING AT RELATIVEn
ROWSET STARTING AT ABSOLUTEn
DB2配列の挿入/フェッチ構文の例と、対応するOracleプリコンパイラ構文との比較を、表8-3に示します。
表8-3 DB2配列構文とOracleプリコンパイラ構文の比較
| DB2の配列構文 | Oracleプリコンパイラの構文 |
|---|---|
EXEC SQL INSERT INTO dsn8810.act (actno, actkwd, actdesc) VALUES (:hva1, :hva2, :hva3) FOR :NUM_ROWS ROWS; |
EXEC SQL FOR :num_rows INSERT INTO dsn8810.act (actno, actkwd, actdesc) VALUES (:hva1, :hva2, :hva3); |
EXEC SQL
FETCH NEXT ROWSET FROM c1
FOR 20 ROWS
INTO :hva_empno, :hva_lastname,
:hva_salary;
|
EXEC SQL
FOR :twenty
FETCH c1
INTO :hva_empno, :hva_lastname,
:hva_salary;
|
DB2の構文では、行セットに位置付けられたカーソルは、データの行セットを取得する前に最初に宣言する必要があります。カーソルが行セットをフェッチできるようにするには、DECLARE CURSOR文で「WITH ROWSET POSITIONING」句を使用する必要があります。これは、次の表に示すように、Oracleプリコンパイラの構文では必要なく、関連もありません。
| DB2の配列構文 | Oracleプリコンパイラの構文 |
|---|---|
EXEC SQL
DECLARE c1 CURSOR
WITH ROWSET POSITIONING FOR
SELECT empno, lastname, salary
FROM dsn8810.emp;
|
EXEC SQL
DECLARE c1 CURSOR FOR
SELECT empno, lastname, salary
FROM dsn8810.emp;
|
このDB2配列構文のサポートは、プリコンパイラ・オプションdb2_arrayを指定して有効にできます。デフォルトのオプションはnoです。DB2配列構文のサポートは、Oracleプリコンパイラ構文と一緒に使用できません。一度にサポートされるのは、Oracleプリコンパイラ構文またはDB2構文のいずれか一方の構文のみです。
例8-1 DB2配列構文使用による行の挿入およびフェッチ
このプログラムでは、DB2の配列INSERT構文を使用して、EMP表にINSCNT行を挿入します。その後、DB2の配列FETCH構文を使用して、挿入された行をフェッチします。
/*
* db2arrdemo.pc
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlcpr.h>
#include <sqlca.h>
/* Number of rows to be inserted in one shot */
#define INSCNT 100
/* Number of rows to be fetched in one shot */
#define FETCHCNT 20
/* Define a host structure
for inserting data into the table
and for fetching data from the table */
struct emprec
{
int empno;
varchar ename[10];
varchar job[9];
int mgr;
char hiredate[10];
float sal;
float comm;
int deptno;
};
typedef struct emprec empdata;
/* Function prototypes */
void sql_error(char *);
void insertdata();
void fetchdata();
void printempdata(empdata *);
void main()
{
exec sql begin declare section;
char *uid = "scott/tiger";
exec sql end declare section;
exec sql whenever sqlerror do sql_error("ORACLE error--\n");
exec sql connect :uid;
printf("Inserting %d rows into EMP table using DB2 array insert syntax.\n",
INSCNT);
insertdata();
printf("\nFetching data using DB2 array fetch syntax.\n");
fetchdata();
exec sql rollback work release;
exit(EXIT_SUCCESS);
}
/* Inserting data into the table using DB2 array insert syntax*/
void insertdata()
{
int i, cnt;
char *str;
empdata emp_in[INSCNT];
/* To store temporary strings */
str = (char *)malloc (25 * sizeof(char));
/* Fill the array elements to insert */
for (i = 0; i < INSCNT; i++)
{
emp_in[i].empno = i+1;
sprintf(str, "EMP_%03d", i+1);
strcpy (emp_in[i].ename.arr, str);
emp_in[i].ename.len = strlen (emp_in[i].ename.arr);
sprintf(str, "JOB_%03d", i+1);
strcpy (emp_in[i].job.arr, str);
emp_in[i].job.len = strlen (emp_in[i].job.arr);
emp_in[i].mgr = i+1001;
sprintf(str, "%02d-MAY-06", (i%30)+1);
strcpy (emp_in[i].hiredate, str);
emp_in[i].sal = (i+1) * 10;
emp_in[i].comm = (i+1) * 0.1;
emp_in[i].deptno = 10;
}
free (str);
/* Inserting data using DB2 array insert syntax */
exec sql insert into emp values (:emp_in) FOR :INSCNT rows;
exec sql select count(*) into :cnt from emp where ename like 'EMP_%';
printf ("Number of rows successfully inserted into emp table: %d\n", cnt);
}
/* Fetches data from the table using DB2 array fetch syntax*/
void fetchdata()
{
empdata emp_out[FETCHCNT];
/* Declares scrollable cursor to fetch data */
exec sql declare c1 scroll cursor with rowset positioning for
select empno, ename, job, mgr, hiredate, sal, comm, deptno
from emp where ename like 'EMP_%' order by empno;
exec sql open c1;
exec sql whenever not found do break;
while(1)
{
/* Fetches data using DB2 array fetch syntax */
exec sql fetch next rowset from c1 for :FETCHCNT rows into :emp_out;
printempdata(emp_out);
}
exec sql whenever not found do sql_error("ORACLE ERROR");
exec sql close c1;
}
/* Prints the fetched employee data */
void printempdata(empdata *emp_out)
{
int i;
for (i=0; i<FETCHCNT; i++)
{
emp_out[i].ename.arr[emp_out[i].ename.len] = '\0';
emp_out[i].job.arr[emp_out[i].job.len] = '\0';
printf("Empno=%d, Ename=%s, Job=%s, Mgr=%d, Hiredate=%s, Sal=%6.2f,\n"
"Comm=%5.2f, Deptno=%d\n", emp_out[i].empno, emp_out[i].ename.arr,
emp_out[i].job.arr, emp_out[i].mgr, emp_out[i].hiredate,
emp_out[i].sal, emp_out[i].comm, emp_out[i].deptno);
}
}
/* Error handling function. */
void sql_error(char *msg)
{
exec sql whenever sqlerror continue;
printf("\n%s\n", msg);
printf("%.70s\n", sqlca.sqlerrm.sqlerrmc);
exec sql rollback release;
exit(EXIT_FAILURE);
}