RESTRICTを指定した場合、SQLではデフォルトの認可識別子に基づいて権限チェックが行われます。モジュールでAUTHORIZATION句を使用して異なる認可識別子を指定しないかぎり、モジュールをコンパイルするユーザーの認可識別子がデフォルトの認可識別子です。RESTRICTオプション句を使用すると、モジュールを実行するユーザーのユーザー名が、デフォルトの認可識別子と比較され、正しい認可識別子を持つユーザー以外のすべてのユーザーは、そのモジュールを起動できなくなります。マルチスキーマを使用するアプリケーションはすべて、デフォルトで実行者となります。
INVOKERを指定した場合、権限はモジュール実行ユーザーの認可識別子に基づきます。
デフォルトはINVOKERです。
ANSI_AUTHORIZATION修飾子は将来のリリースで廃止予定のため、RIGHTS句を使用してください。
SCHEMA句を使用すると、個々のSQLモジュールがそれぞれ異なるスキーマをデフォルト・スキーマとして宣言できます。これは、複数のスキーマを参照する必要のあるアプリケーションで便利な場合があります。適切なモジュールのプロシージャでスキーマを参照するSQL文を配置すると、それらの文のスキーマ要素名の冗長な修飾を最小限に抑えることができます。
SCHEMA schema-name AUTHORIZATION authorization-nameを指定する場合は、モジュールのスキーマ名およびスキーマ認可識別子を指定します。スキーマ認可識別子は、スキーマの所有者および作成者であるとみなされ、すべての権限が含まれます。
エントリ・レベルSQL92またはその下位レベルに対してFIPSフラガーが有効である場合、SCHEMA句(単独で、またはAUTHORIZATION句とともに使用)は非標準のANSI構文としてフラグが付けられます。
SQLモジュールのプロシージャが常に認可識別子で表名を修飾する場合、SCHEMA句はプロシージャのSQL文には影響しません。
仮パラメータとしてのSQLCAの指定は、SQLCODEの指定の代替手段です。SQLCODEのかわりにSQLCAを使用すると、SQLCAのSQLERRD配列の第3要素に入る情報をコール側プログラム・モジュールで利用できます。SQLの将来のバージョンでは、追加情報に対してSQLCAを使用できる可能性もあります。
SQLCODEではなくSQLSTATEステータス・パラメータを使用することをお薦めします。SQLSTATEはANSI/ISO SQL規格に準拠しており、SQLCODEは将来のリリースのOracle Rdbで廃止される可能性があります。
SQLCODEの詳細は、表C-1を参照してください。
SQLCODEではなくSQLSTATEステータス・パラメータを使用することをお薦めします。SQLSTATEはANSI/ISO SQL規格に準拠しており、SQLCODEは将来のリリースのOracle Rdbで廃止される可能性があります。
SQL92、SQL99、SQL89またはMIAを指定した場合、SQLモジュール・プロセッサによりその更新可能ビューのANSI/ISO規格がコンパイル時に作成されるすべてのビューに適用されます。更新可能ビューに関するANSI/ISO規格に準拠しないビューは、更新できません。デフォルトはSQLV40です。
更新可能ビューに関するANSI/ISO SQL規格では、SELECT文で次の条件が満たされる必要があります。
SQLV40を指定した場合、SQLではANSI/ISO規格は更新可能ビューに適用されません。かわりに、次の条件を満たすビューは更新可能とみなされます。
- SQLモジュール内のプロシージャの順序は任意です。ホスト言語モジュールからコールされる順序と一致している必要はありません。
- SQLモジュール・プロセッサを使用してCモジュール言語を指定する場合、C文字列はすべてヌル文字で終了する文字列として変換されます。つまり、これらの文字列がデータベースからプログラムに渡される場合、ヌル文字用として文字列の最後に空白が確保されます。入力のために文字列がデータベースに渡される場合、データベースに格納する文字数を確認するためにこのヌル文字が検索されます。データベースにはヌル文字の前にある文字のみが格納され、ヌル文字は格納されません。
SQLによるC文字列の変換方法のため、バイナリ・データをデータベースと相互に渡すアプリケーションで問題が発生する可能性があります。Cホスト言語プログラムでSQLモジュール言語を使用する際にこれらの問題を回避するには、モジュール言語をGENERALとして指定します。
ディクショナリからデータ定義を取得する際、FROM path-name句のrecord-type句で文字解析オプションを指定すると、文字データのデフォルトの変換を変更できます。詳細は、「引数」の項のFIXED、NULL TERMINATED BYTESおよびNULL TERMINATED CHARACTERSの説明を参照してください。
また、SQLによるC文字列の変換方法は、データ・ディクショナリからレコード定義をコピーするためにSQL INCLUDE句またはSQL FROM path-name句を使用するプログラムに影響します。- ダブル・ハイフン(-)は、行の残りのテキストがすべてコメントであることを指定します。したがって、SQLモジュール・プロセッサでは、ソース・ファイルを処理するときにダブル・ハイフンの右側にあるテキストがすべて無視されます。空白行を使用して、SQLモジュール・ソース・ファイルを読みやすく、および理解しやすくできます。また、SQLモジュール・プロセッサに必要なコードと同じ行(コードの右側)でコメントを指定することもできます。次に例を示します。
DECLARE VI_DB ALIAS FOR FILENAME personnel -- Declare the alias for the database.
- SQLモジュールでは、キーワード、ユーザー定義の名前またはリテラル(引用符付き文字列など)を1行から次の行に継続できません。SQLモジュール・ソース・ファイルでは、これらを1行に完全に収めます。
- SQLモジュールをコールし、エラー処理のためにSQLCAおよびメッセージ・ベクターを必要とするプログラムでは、この構造体を明示的に宣言する必要があります。SQLCAおよびメッセージ・ベクターの宣言の詳細は、付録Cを参照してください。
- sql_signalルーチンおよびsql_get_error_textルーチンなどのSQLエラー処理ルーチンをモジュール言語プログラムで使用できます。詳細は、『Oracle Rdb7 Guide to SQL Programming』を参照してください。
- SQLモジュールでは、WHENEVER文を指定できません。また、プリコンパイルされるホスト言語ソース・ファイルにWHENEVER文を組み込み、それをSQLモジュール・プロシージャへのコールに適用することもできません。WHENEVER文は、ホスト言語ソース・ファイルに組み込まれたSQL文のみを識別できるSQLプリコンパイラでのみサポートされます。
組込みWHENEVER文のかわりに、条件付きホスト言語文を使用して、コールの直後にSQL文のステータス・フィールド(SQLCAでSQLCODEと呼ばれる)またはSQLSTATEステータス・パラメータ(ANSI/ISO SQL規格)を評価します。プログラムでのエラー処理の詳細は、『Oracle Rdb7 Guide to SQL Programming』のランタイム・エラーに関する章を参照してください。- ホスト言語プログラム・モジュールでは、コール内で複数のSQLモジュールを参照できます。
- DECLARE TABLE文がCREATE DATABASE文の前に出現する場合は、SQL$DATABASEまたはSQL_DATABASEをオープンできないまたは特定のデータベース・オブジェクトがデータベース内に存在しないことを示すエラー・メッセージが表示され、コンパイルが失敗する可能性があります。
SQLモジュール言語のコンパイラでは、他の文の前にメタデータ文が処理されます。DECLARE TABLE文がそれを定義するCREATE DATABASE文(またはCREATE ALIAS文)の前に出現する場合、メタデータ検索用にSQL$DATABASEまたはSQL_DATABASEへのアタッチが試行されます。
CREATE DATABASE文またはCREATE ALIAS文を、DECLARE TABLE文の前に配置してください。
例1: PascalプログラムからのSQLモジュール・プロシージャのコール次の例は、SQLモジュール・ファイルにあるプロシージャをコールするPascalプログラムです。
PROGRAM list_employees(OUTPUT); { Program to list employees' names whose last name matches a LIKE predicate. Note the following: 1) The input parameter (like_string) to the SELECT expression in the DECLARE CURSOR is supplied on the OPEN_CURSOR call. 2) The output parameters are returned on each FETCH_INTO call. 3) The cursor is closed after the desired rows are processed, so that it will be positioned properly in subsequent operations. } TYPE LAST_NAME = PACKED ARRAY[1..14] OF CHAR; FIRST_NAME = PACKED ARRAY[1..10] OF CHAR; VAR { Variable data } sqlcode : INTEGER := 0; emp_last : LAST_NAME; emp_first: FIRST_NAME; like_string : LAST_NAME := 'T_ _ _ _ _ _ _ _ _ _ _ _ _'; { Declarations of entry points in the SQL module } PROCEDURE SET_TRANS (VAR sqlcode : INTEGER); EXTERNAL; PROCEDURE OPEN_CURSOR (VAR sqlcode: INTEGER; name : LAST_NAME); EXTERNAL; PROCEDURE FETCH_INTO (VAR sqlcode : INTEGER; VAR last : LAST_NAME; VAR first : FIRST_NAME); EXTERNAL; PROCEDURE CLOSE_CURSOR (VAR sqlcode : INTEGER); EXTERNAL; PROCEDURE ROLLBACK_TRANS (VAR sqlcode : INTEGER); EXTERNAL; BEGIN SET_TRANS (sqlcode); { Start a read-only transaction.} OPEN_CURSOR (sqlcode, like_string);{ Open the cursor, supplying } { the string to match against. } WRITELN('Matching Employees:'); { Print header. } REPEAT { Iterate matching names. } BEGIN FETCH_INTO (sqlcode, emp_last, emp_first);{ Fetch the next name. } IF sqlcode = 0 THEN WRITELN(emp_first, emp_last); { Print employee information. } END UNTIL sqlcode <> 0; IF sqlcode <> 100 { Print any error information. } THEN WRITELN ('SQL error code = ', sqlcode); CLOSE_CURSOR (sqlcode); { Finish the cursor operation. } ROLLBACK_TRANS (sqlcode); { Finish the transaction. } END.
このプログラムからコールするSQLモジュール・ファイルを次に示します。
MODULE employees LANGUAGE PASCAL AUTHORIZATION SQL_USER ALIAS RDB$DBHANDLE DECLARE ALIAS FOR FILENAME PERSONNEL DECLARE names CURSOR FOR SELECT LAST_NAME, FIRST_NAME FROM EMPLOYEES WHERE LAST_NAME LIKE match_string PROCEDURE SET_TRANS SQLCODE; SET TRANSACTION READ ONLY; PROCEDURE OPEN_CURSOR SQLCODE match_string CHAR(14); OPEN names; PROCEDURE FETCH_INTO SQLCODE l_name CHAR(14) f_name CHAR(10); FETCH names INTO l_name, f_name; PROCEDURE CLOSE_CURSOR SQLCODE; CLOSE names; PROCEDURE ROLLBACK_TRANS SQLCODE; ROLLBACK;
例2: CプログラムからのSQLモジュール・プロシージャのコール
次の例は、SQLモジュール・ファイルにあるプロシージャをコールするCプログラムです。
/* C program to list employees' names where the last name matches a LIKE predicate. Note the following: 1) The input parameter (like_string) to the SELECT expression in the DECLARE CURSOR is supplied on the OPEN_CURSOR call. 2) The output parameters are returned on each FETCH_INTO call. 3) The cursor is closed after the desired rows are processed, so that it will be positioned properly in subsequent operations. */ #include <stdio.h> #pragma dictionary "name" typedef struct name NAME_TYPE; extern void FETCH_INTO (int *sqlcode, NAME_TYPE *name_record); typedef char LAST_NAME[15]; typedef int *SQLCODE; /* Declarations of entry points in the SQL module */ extern void SET_TRANS (int *sqlcode); extern void OPEN_CURSOR (int *sqlcode, LAST_NAME name); extern void CLOSE_CURSOR (int *sqlcode); extern void ROLLBACK_TRANS (int *sqlcode); void main () { int sqlcode = 0; NAME_TYPE name_record; LAST_NAME like_string = "T%"; SET_TRANS (&sqlcode); /* Start a read-only transaction. */ if (sqlcode != 0) /* Print any error information. */ printf ("SQL error code = %d\n", sqlcode); OPEN_CURSOR (&sqlcode, like_string); /* Open the cursor, supplying */ /* the string to match against. */ if (sqlcode != 0) /* Print any error information. */ printf ("SQL error code = %d\n", sqlcode); printf ("Matching Employees:\n"); /* Print header. */ do /* Iterate matching names. */ { FETCH_INTO (&sqlcode, &name_record);/* Fetch the next name. */ if (sqlcode == 0) printf ("%s%s\n", name_record.f_name, name_record.l_name); } /* Print employee information. */ while (sqlcode == 0); if (sqlcode != 100) /* Print any error information. */ printf ("SQL error code = %d\n", sqlcode); CLOSE_CURSOR (&sqlcode); /* Complete the cursor operation. */ if (sqlcode != 0) /* Print any error information. */ printf ("SQL error code = %d\n", sqlcode); ROLLBACK_TRANS (&sqlcode); /* Finish the transaction. */ if (sqlcode != 0) /* Print any error information. */ printf ("SQL error code = %d\n", sqlcode); }
このプログラムからコールするSQLモジュール・ファイルを次に示します。
MODULE employees LANGUAGE C AUTHORIZATION SQL_USER ALIAS RDB$DBHANDLE DECLARE ALIAS FOR PATHNAME 'MF_PERSONNEL' DECLARE names CURSOR FOR SELECT LAST_NAME, FIRST_NAME FROM EMPLOYEES WHERE LAST_NAME LIKE match_string PROCEDURE SET_TRANS SQLCODE; SET TRANSACTION READ ONLY; PROCEDURE OPEN_CURSOR SQLCODE match_string CHAR(14); OPEN names; PROCEDURE FETCH_INTO SQLCODE, name_record RECORD FROM 'name' END RECORD; FETCH names INTO name_record; PROCEDURE CLOSE_CURSOR SQLCODE; CLOSE names; PROCEDURE ROLLBACK_TRANS SQLCODE; ROLLBACK;
CプログラムおよびSQLモジュールで使用されるメタデータを定義するCDOコマンド・ファイルを次に示します。SQLモジュール・ファイルのmatch_stringでは14文字のみが有効ですが、フィールドL_NAMEは15文字です。Cプログラミング言語では文字レコードが使用され、最大14文字と、文字列用にCプログラムでデフォルトで必要となるヌル終端文字のみを格納できます。他の文字列解析オプションについては、例3を参照してください。
! MOD_LANG.CDO ! ! This file defines an Oracle CDD/Repository record to be used by ! the SQL module language module called from a C program. ! DEFINE FIELD L_NAME DATATYPE TEXT 15. DEFINE FIELD F_NAME DATATYPE TEXT 11. DEFINE RECORD NAME. L_NAME. F_NAME. END RECORD.
例3: 3つの異なるC言語解析オプションのためのテキスト・フィールドの宣言
/* SQL$TEXT_FIELDS.C * This program demonstrates the use of DEC C and the SQL module language * to show different formats for text fields from the record PARTS, * stored in the repository. The program tests each fetched field * to make sure that it ends in a null character if it is supposed to. * * The program calls the SQL module SQL$TEXT_FIELDS_C.SQLMOD. * To create and populate the database for this example, you must run * the command procedure SQL$TEXT_FIELDS.SQL. You must also have the * data dictionary installed on your system. * */ #include stdio main() { int sqlcode; int i; int fixed_okay; /* Host variables for SQL calls. * Structure P_NTC shows the definition for a text * string interpreted with the NULL TERMINATED CHARACTERS option. * Character strings for P_NTC are 1 byte longer than those * character strings in the other three structures. * A field with a length of 7 bytes contains 6 characters * followed by the null value. */ struct { char pnum[7]; char pname[21]; char color[7]; short weight; char city[16]; } p_ntc; /* * Structure P_NTB shows the definition for a text * string interpreted with the NULL TERMINATED BYTES option. * A field with a length of 6 bytes contains 5 characters * followed by the null value. */ struct { char pnum[6]; char pname[20]; char color[6]; short weight; char city[15]; } p_ntb; /* * Structure P_DEFAULT shows the definition for a text * string interpreted without a character interpretation * option. The default interpretation is the same as * NULL TERMINATED BYTES; a field with a length of 6 bytes * contains 5 characters followed by the null value. */ struct { char pnum[6]; char pname[20]; char color[6]; short weight; char city[15]; } p_default; /* * Structure P_FIXED shows the definition for a text * string interpreted with the FIXED option. * A field with a length of 6 bytes contains 6 * characters. There is no null value added to the field. */ struct { char pnum[6]; char pname[20]; char color[6]; short weight; char city[15]; } p_fixed; open_p( &sqlcode ); fetch_p_default( &sqlcode, &p_default ); close_p( &sqlcode ); printf( "%s, %s, %s, %s\n", p_default.pnum, p_default.pname,p_default.color, p_default.city ); for (i=0;i<6;i++) { if (p_default.pnum[i] == '\0') { if (i != 5) { printf("NULL not terminating in DEFAULT\n"); } else { printf("DEFAULT is okay\n"); } } } open_p( &sqlcode ); fetch_p_fixed( &sqlcode, &p_fixed ); close_p( &sqlcode ); printf( "%0.6s, %0.20s, %0.6s, %0.15s\n", p_fixed.pnum, p_fixed.pname,p_fixed.color, p_fixed.city ); fixed_okay = 1; for (i=0;i<6;i++) { if (p_fixed.pnum[i] == '\0') { fixed_okay = 0; }; }; if (fixed_okay == 0) { printf("NULL in fixed string\n"); } else { printf("FIXED is okay\n"); }; open_p( &sqlcode ); fetch_p_ntb( &sqlcode, &p_ntb ); close_p( &sqlcode ); printf( "%s, %s, %s, %s\n", p_ntb.pnum, p_ntb.pname,p_ntb.color, p_ntb.city ); for (i=0;i<6;i++) { if (p_ntb.pnum[i] == '\0') { if (i != 5) { printf("NULL not terminating in NTB\n"); } else { printf("NTB is okay\n"); } } } open_p( &sqlcode ); fetch_p_ntc( &sqlcode, &p_ntc ); close_p( &sqlcode ); printf( "%s, %s, %s, %s\n", p_ntc.pnum, p_ntc.pname,p_ntc.color, p_ntc.city ); for (i=0;i<7;i++) { if (p_ntc.pnum[i] == '\0') { if (i != 6) { printf("NULL not terminating in NTC\n"); } else { printf("NTC is okay\n"); } } } }
このプログラムからコールするSQLモジュール・ファイルを次に示します。
-- This SQL module provides the SQL procedures needed by the -- SQL$TEXT_FIELDS.C program. The module illustrates the three -- different ways that you can specify text fields in the -- repository using the C programming language: -- NULL TERMINATED BYTES, the default -- NULL TERMINATED CHARACTERS -- FIXED (no null) -- FIXED (no null) -- -- Because this module precedes parameter names with colons, -- in compliance with the ANSI/ISO SQL standard, you must supply -- the PARAMETER COLONS clause in the module header. ------------------------------------------------------------------------------- -- Header Information Section ------------------------------------------------------------------------------- MODULE SQL_TEXT_FIELDS_C LANGUAGE C AUTHORIZATION SQL_SAMPLE PARAMETER COLONS ------------------------------------------------------------------------------- -- DECLARE Statements Section ------------------------------------------------------------------------------- DECLARE ALIAS FILENAME 'SUPPLIES' DECLARE P_CURSOR CURSOR FOR SELECT * FROM PARTS ------------------------------------------------------------------------------- -- Procedure Section -- In every procedure, declare SQLCODE, a parameter that stores a value -- representing the execution status of SQL statements. ------------------------------------------------------------------------------- PROCEDURE open_p SQLCODE; OPEN P_CURSOR; -- This procedure specifies the repository record PARTS using the -- repository path name. Because none of the character interpretation -- options is specified, output for a field defined as TEXT SIZE 6 -- in the repository or CHAR (6) in SQL will show the default interpretation, -- NULL TERMINATED BYTES, a field of 6 bytes that contains 5 -- characters followed by a null value. PROCEDURE fetch_p_default SQLCODE :P_REC RECORD FROM 'CDD$DEFAULT.SUPPLIES.RDB$RELATIONS.PARTS' END RECORD; FETCH P_CURSOR INTO :P_REC; -- This procedure specifies the repository record PARTS using the -- repository path name. Because the FIXED option is specified, -- output for a field defined as TEXT SIZE 6 in the repository or -- CHAR (6) in SQL will be a field of 6 bytes that contains -- 6 characters. There is no null value. PROCEDURE fetch_p_fixed SQLCODE :P_REC RECORD FROM 'CDD$DEFAULT.SUPPLIES.RDB$RELATIONS.PARTS' FIXED END RECORD; FETCH P_CURSOR INTO :P_REC; -- This procedure specifies the repository record PARTS using the -- repository path name. Because the NULL TERMINATED BYTES -- option is specified, output for a field defined as TEXT SIZE 6 -- in the repository or CHAR (6) in SQL will be a field of 6 bytes -- that contains 5 characters followed by the null value. PROCEDURE fetch_p_ntb SQLCODE :P_REC RECORD FROM 'CDD$DEFAULT.SUPPLIES.RDB$RELATIONS.PARTS' NULL TERMINATED BYTES END RECORD; FETCH P_CURSOR INTO :P_REC; -- This procedure specifies the repository record PARTS using the -- repository path name. Because the NULL TERMINATED CHARACTERS -- option is specified, output for a field defined as TEXT SIZE 6 -- in the repository or CHAR (6) in SQL will be a field of 7 -- bytes that contains 6 characters followed by the null value. PROCEDURE fetch_p_ntc SQLCODE :P_REC RECORD FROM 'CDD$DEFAULT.SUPPLIES.RDB$RELATIONS.PARTS' NULL TERMINATED CHARACTERS END RECORD; FETCH P_CURSOR INTO :P_REC; PROCEDURE close_p SQLCODE; CLOSE P_CURSOR;
これらの例で使用されるデータベースを作成および移入するSQLコマンド・プロシージャを次に示します。
! ! This SQL procedure creates and populates the database used by ! the module language file SQL$TEXT_FIELDS_C.SQLMOD. ! SET VERIFY CREATE DATABASE FILENAME PERSONNEL PATHNAME 'CDD$TOP.PERSONNEL'; CREATE TABLE S (SNUM CHAR (5), SNAME CHAR (20), STATUS SMALLINT, CITY CHAR(15)); CREATE TABLE P (PNUM CHAR (6), PNAME CHAR(20), COLOR CHAR(6), WEIGHT SMALLINT, CITY CHAR(15)); INSERT INTO P ( PNUM, PNAME, COLOR, WEIGHT, CITY ) VALUES ('P1', 'Nut', 'Red', 12, 'London' ); COMMIT; DISCONNECT ALL;