ある環境で開発した複数のモジュールを統合して、別の環境にデプロイするアプリケーション開発環境では、アプリケーションのパフォーマンスが影響を受けます。プリコンパイラ・アプリケーションのパフォーマンスは、データベース環境の変更によって影響を受けることがあります。これらの変更には、オプティマイザ統計の変更、オプティマイザ設定の変更またはメモリー構造のサイズに影響するパラメータの変更が含まれます。
開発環境においてPro*C/C++で使用されるSQLの実行計画を修正するには、プリコンパイル時にOracleのアウトライン機能を使用する必要があります。アウトラインは、SQL文と関連付けられた一連のオプティマイザ・ヒントとして実装されます。SQL文のアウトラインの使用を有効にすると、Oracleでは、格納されたヒントが自動的に考慮され、それらのヒントに従って実行計画を生成しようとします。これにより、モジュールの統合時および異なる環境へのデプロイ時に、パフォーマンスは影響を受けません。
次のSQL文を使用して、Pro*C/C++でアウトラインを作成できます。
SELECT
DELETE
UPDATE
INSERT ... SELECT
CREATETABLE...ASSELECT
アウトライン・オプションが設定されている場合、プリコンパイルが正常に終了すると、2つのファイル(SQLファイルおよびLOGファイル)が生成されます。コマンドライン・オプションoutlineおよびoutlnprefixは、アウトラインの生成を制御します。
生成される各アウトライン名は一意です。アプリケーションで使用するファイル名が一意であるため、アウトライン名の生成時にこの情報が使用されます。また、カテゴリ名も接頭辞として使用されます。
注意:
アウトライン名の最大長は30バイトです。この制限を超えると、プリコンパイラではエラーが発生します。outlnprefixオプションを使用すると、アウトライン名の長さを制限できます。
例6-1 アウトラインを含むSQLファイルの生成
次のプログラムのアウトラインがサポートされているすべてのSQL文のアウトラインを含むSQLファイルを生成するには、アウトライン・オプションを使用して、次のプログラムをプリコンパイルする必要があります。
/*
* outlndemo.pc
*
* Outlines will be created for the following SQL operations,
* 1. CREATE ... SELECT
* 2. INSERT ... SELECT
* 3. UPDATE
* 4. DELETE
* 5. SELECT
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlcpr.h>
#include <sqlca.h>
/* 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);
}
int main()
{
varchar ename[10];
varchar job[9];
float sal, comm;
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;
exec sql insert into bonus
select ename, job, sal, comm from emp where job like 'SALESMAN';
exec sql update bonus set sal = sal * 1.1 where sal < 1500;
exec sql declare c1 cursor for
select ename, job, sal, comm from bonus order by sal;
exec sql open c1;
printf ("Contents of updated BONUS table\n\n");
printf ("ENAME JOB SALARY COMMISSION\n\n");
exec sql whenever not found do break;
while (1)
{
exec sql fetch c1 into :ename, :job, :sal, :comm;
ename.arr[ename.len]='\0';
job.arr[job.len]='\0';
printf ("%-9s %-9s %8.2f %8.2f\n", ename.arr,
job.arr, sal, comm);
}
exec sql close c1;
exec sql whenever not found do sql_error("ORACLE error--\n");
exec sql delete from bonus;
exec sql create table outlndemo_tab as
select empno, ename, sal from emp where deptno = 10;
/* Outline will not be created for this DDL statement */
exec sql drop table outlndemo_tab;
exec sql rollback work release;
exit(EXIT_SUCCESS);
}
生成されるファイル名の書式は次のとおりです。
<filename>_<filetype>.sql
Pro*Cでは、ファイル「abc.pc」の場合、生成されるSQLファイルはabc_pc.sqlになります。
生成されるファイル書式
outlnprefixオプションを使用しない場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。
<category_name>_<filename>_<filetype>_<sequence no.>
outlnprefixオプションを使用する(outlnprefix=<prefix_name>)場合は、アウトライン名およびコメントとして、次の一意識別子の書式が使用されます。
<prefix_name>_<sequence no.>
outline=yes (デフォルトのカテゴリ)の場合、<category_name>はDEFAULTに、アウトライン名は次のいずれかになります。
DEFAULT_<filename>_<filetype>_<sequence no.>
または
<prefix_name>_<sequence no.>
<sequence no.>に使用できる値の範囲は、0000から9999です。
生成されたプリコンパイル済ファイルのSQLには、SQLのアウトラインで表示されるように、コメントが追加されます。
次の例を考えてみます。
例1
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=mycat1で、outlnprefixを使用しない場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* mycat1_abc_pc_0000 */;で、カテゴリmycat1のアウトラインmycat1_abc_pc_0000を作成または置換します。
select * from dept /* mycat1_abc_pc_0001 */;で、カテゴリmycat1のアウトラインmycat1_abc_pc_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = select * from emp where empno=:b1 /* mycat1_abc_pc_0000 */; sqlstm.stmt = select * from dept /* mycat1_abc_pc_0001 */;
例2
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=mycat1で、outlnprefix=myprefixの場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* myprefix_0000 */;で、カテゴリmycat1のアウトラインmyprefix_0000を作成または置換します。
select * from dept /* myprefix_0001 */;で、カテゴリmycat1のアウトラインmyprefix_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = select * from emp where empno=:b1 /* myprefix_0000 */; sqlstm.stmt = select * from dept /* myprefix_0001 */;
例3
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp where empno=:var; EXEC SQL select * from dept;
outline=yesで、outlnprefix=myprefixの場合は、次のようになります。
abc_pc.sqlの内容
select * from emp where empno=:b1 /* myprefix_0000 */;で、アウトラインmyprefix_0000を作成または置換します。
select * from dept /* myprefix_0001 */;で、アウトラインmyprefix_0001を作成または置換します。
abc.cの内容
sqlstm.stmt = "select * from emp where empno=:b1 /* myprefix_0000 */; sqlstm.stmt = "select * from dept /* myprefix_0001 */";
生成されるファイル名の書式は次のとおりです。
<filename>_<filetype>.log
Pro*Cでは、ファイル「abc.pc」の場合、生成されるLOGファイルはabc_pc.logになります。
次に例を示します。
例1
abc.pcには、次の文が含まれています。
EXEC SQL select * from emp;
abc_pc.logの内容
CATEGORY <Category_name>
Source SQL_0
SELECT * FROM emp
OUTLINE NAME
abc_pc_0000
OUTLINE SQL_0
Select * from emp /* abc_pc_0000 */