Programmer's Guide to the Pro*C/C++ Precompiler | ![]() Library |
![]() Product |
![]() Contents |
![]() Index |
proc
The location of the precompiler differs from system to system. The system or database administrator usually defines logicals or aliases, or uses other system-specific means to make the Pro*C executable accessible.
The INAME= argument specifies the source file to be precompiled. For example, the command
proc INAME=test_proc
precompiles the file test_proc.pc in the current directory, since the precompiler assumes that the filename extension is .pc. The INAME option does not have to be the first option on the command line, but if it is, you can omit the option specification. So, the command
proc myfile
is equivalent to
proc INAME=myfile
Note: The option names, and option values that do not name specific OS objects, such as filenames, are not case-sensitive. In the examples in this guide, option names are written in upper case, and option values are usually in lower case. When you enter filenames, including the name of the Pro*C precompiler executable itself, always follow the case conventions used by your operating system. In UNIX, the executable is ``proc'', in lower case.
The value of an option is a string literal, which represent text or numeric values. For example, for the option
... INAME=my_test
the value is a string literal that specifies a filename. But for the option
...MAXOPENCURSORS=20
the value is numeric.
Some options take Boolean values, and you can represent these with the strings yes or no, true or false, or with the integer literals 1 or 0 respectively. For example, the option
... SELECT_ERROR=yes
is equivalent to
... SELECT_ERROR=true
or
... SELECT_ERROR=1
all of which mean that SELECT errors should be flagged at run time.
The option value is always separated from the option name by an equals sign, with no whitespace around the equals sign.
Finally, an inline specification takes precedence over all preceding defaults. See the section "Configuration Files" for more information about configuration files.
Some options, such as USERID, do not have a precompiler default value. The built-in default values for options that do have them are listed in Table 7 - 1, and in the "Using the Precompiler Options" section starting .
proc ?
the complete set of options, along with their current values, is printed to your terminal. (On a UNIX system running the C shell, escape the `?' with a backslash.) In this case, the values are those built into the precompiler, overridden by any values in the system configuration file. But if you issue the command
proc config=my_config_file.h ?
and there is a file named my_config_file.h in the current directory, all options are listed. Values in the user configuration file supply missing values, and supersede values built-in to the Pro*C precompiler, or values specified in the system configuration file.
You can also determine the current value of a single option, by simply specifying that option name, followed by =?. For example
proc maxopencursors=?
prints the current default value for the MAXOPENCURSORS option.
FIPS=YES
MODE=ANSI
CODE=ANSI_C
to set defaults for the FIPS, MODE, and CODE options.
There is a single system configuration file for each Oracle installation. The name of the system configuration file is pmscfg.h. The location of the file is system specific. On most UNIX systems, the file specification is $ORACLE_HOME/proc/pmscfg.h.
Each Pro*C user can have one or more private configuration files. The name of the configuration file must be specified using the CONFIG= precompiler option. See the "Using the Precompiler Options" section starting .
Note: You cannot nest configuration files. This means that CONFIG= is not a valid option inside a configuration file.
Note: The precompiler does not generate calls to Oracle Call Interface (OCI) routines.
The precompiler can issue warnings and error messages. These messages have the prefix PCC-, and are described in the Oracle7 Server Messages manual.
Table 7 - 1 is a quick reference to the major precompiler options. It summarizes the section "Using the Precompiler Options" starting . The options that are accepted, but do not have any affect, are not included in this table.
... [OPTION_NAME=value] [OPTION_NAME=value] ...
Separate each option=value specification with one or more spaces. For example, you might enter the following:
... CODE=ANSI_C MODE=ANSI
EXEC ORACLE OPTION (OPTION_NAME=value);
For example, you might code the following:
EXEC ORACLE OPTION (RELEASE_CURSOR=yes);
An option entered inline overrides the same option entered on the command line, or specified in a configuration file.
Specifying options inline or in a configuration file is also helpful if your operating system limits the number of characters you can enter on the command line.
char emp_name[20]; int emp_number, dept_number; float salary; EXEC SQL WHENEVER NOT FOUND DO break; EXEC ORACLE OPTION (HOLD_CURSOR=NO); EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT empno, deptno FROM emp; EXEC SQL OPEN emp_cursor; printf( "Employee Number Department\n--------------------------\n"); for (;;) { EXEC SQL FETCH emp_cursor INTO :emp_number, :dept_number; printf("%d\t%d\n", emp_number, dept_number); } EXEC SQL WHENEVER NOT FOUND CONTINUE; for (;;) { printf("Employee number: "); scanf("%d", &emp_number); if (emp_number == 0) break; EXEC ORACLE OPTION (HOLD_CURSOR=YES); EXEC SQL SELECT ename, sal INTO :emp_name, :salary FROM emp WHERE empno = :emp_number; printf("Salary for %s is %6.2f.\n", emp_name, salary); }
If AUTO_CONNECT=YES, and the application is not already connected to a database when it processes the first executable SQL statement, it attempts to connect using the userid
OPS$<username>
where username is your current operating system user or task name and OPS$username is a valid Oracle userid.
When AUTO_CONNECT=NO, you must use the CONNECT statement in your program to connect to Oracle.
ANSI C standard X3.159-1989 provides for function prototyping. When CODE=ANSI_C, Pro*C/C++ generates full function prototypes, which conform to the ANSI C standard. An example follows:
extern void sqlora(long *, void *);
The precompiler can also generate other ANSI-approved constructs such as the const type qualifier.
When CODE=KR_C (the default), the precompiler comments out the argument lists of generated function prototypes, as shown here:
extern void sqlora(/*_ long *, void * _*/);
So, specify CODE=KR_C if your C compiler is not compliant with the X3.159 standard.
When CODE=CPP, the precompiler generates C++ compatible code.
With COMP_CHARSET=MULTI_BYTE (default), Pro*C/C++ generates C code that is to be compiled by a compiler that supports multi-byte NLS character sets.
With COMP_CHARSET=SINGLE_BYTE, Pro*C/C++ generates C code for single-byte compilers that addresses a complication that may arise from the ASCII equivalent of a backslash (\) character in the second byte of a double-byte character in a multi-byte string. In this case, the backslash (\) character is "escaped" with another backslash character preceding it.
Note: The need for this feature is common when developing in a Shift-JIS environment with older C compilers.
This option has no effect when NLS_LANG is set to a single-byte character set.
This option is the only way you can inform Pro*C/C++ of the name and location of user configuration files.
The DBMS option lets you control the version-specific behavior of Oracle. When DBMS=NATIVE (the default), Oracle follows the semantic and syntactic rules of the database version to which the application is connected.
When DBMS=V6, V6_CHAR, or DBMS=V7, Oracle follows the respective rules for Oracle Version 6 or Oracle7. A summary of the differences between DBMS=V6, DBMS=V6_CHAR, and DBMS=V7 follows:
CREATE TABLE T1 (COL1 CHAR(10))
creates the table using the VARCHAR2 (variable-length) datatype, just as if the CREATE TABLE statement had been
CREATE TABLE T1 (COL1 VARCHAR2(10))
When DEF_SQLCODE=YES, the precompiler defines SQLCODE in the generated source code as follows:
#define SQLCODE sqlca.sqlcode
You can then use SQLCODE to check the results of executable SQL statement. The DEF_SQLCODE option is supplied for compliance with standards that require the use of SQLCODE.
In addition, you must also include the SQLCA using one of the following entries in your source code:
#include <sqlca.h>
or
EXEC SQL INCLUDE SQLCA;
If the SQLCA is not included, using this option causes a precompile time error.
proc my_prog DEFINE=LEN=20
Using DEFINE in the correct way, you could do
proc my_prog DEFINE=XYZZY
And then in my_prog.pc, code
#ifdef XYZZY ... #else ... #endif
Or you could just as well code
EXEC ORACLE IFDEF XYZZY; ... EXEC ORACLE ELSE; ... EXEC ORACLE ENDIF;
The following example is invalid:
#define XYZZY ... EXEC ORACLE IFDEF XYZZY ... EXEC ORACLE ENDIF;
EXEC ORACLE conditional statements are valid only if the macro is defined using EXEC ORACLE DEFINE or the DEFINE option.
If you define a name using DEFINE=, and then conditionally include (or exclude) a code section using the Pro*C preprocessor #ifdef (or #ifndef) directives, you must also make sure that the name is defined when you run the C compiler. For example, for UNIX cc, you must use the -D option to define the name for the C compiler.
When FIPS=YES, the FIPS Flagger is enabled, and warning (not error) messages are issued if you use an Oracle extension to ANSI SQL, or use an ANSI SQL feature in a nonconforming manner. Extensions to ANSI SQL that are flagged at precompile time include the following:
Pro*C/C++: Release 2.1.1.0.0 - Beta on Thu Sep 22 14:28:43 1994 Copyright (c) Oracle Corporation 1979, 1994. All rights reserved. System default option values taken from: /private2/dve/k72tt/proc/pcscfg.h Oracle FIPS Flagging Report Version 1.0 - Development This report lists extensions to ANSI SQL document X3.168-1989 The following extensions were detected: Violation Line Number Description --------- ----------- ------------------------------------- 00707 106 keyword WORK required after ROLLBACK 00709 106 use of RELEASE clause 00710 65 use of dynamic SQL 00717 28 56 use of DO within WHENEVER clause 00724 22 53 invalid datatype The following non-standard usages were detected: No extensions were detected.
The following extensions which will become standard in a future release of the SQL standard were detected: Violation Revision Line Number Description --------- ----------- ----------- -------------------------- 00704 SQL 2 Draft 30 use of the CONNECT statement The following deprecated features were detected: No extensions were detected. Found 6 violations of ANSI SQL standard X3.168-1989. ANSI SQL document comparison cross-reference by line number: Line Numbers Document Referenced ------------ ------------------- 1 - end X3.168-1989 The Oracle FIPS Flagger was active for all lines in the source.
You can use HOLD_CURSOR to improve the performance of your program. For more information, see Appendix C.
When a SQL data manipulation statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache entry is in turn linked to an Oracle private SQL area, which stores information needed to process the statement. HOLD_CURSOR controls what happens to the link between the cursor and cursor cache.
When HOLD_CURSOR=NO, after Oracle executes the SQL statement and the cursor is closed, the precompiler marks the link as reusable. The link is reused as soon as the cursor cache entry to which it points is needed for another SQL statement. This frees memory allocated to the private SQL area and releases parse locks.
When HOLD_CURSOR=YES and RELEASE_CURSOR=NO, the link is maintained; the precompiler does not reuse it. This is useful for SQL statements that are executed often because it speeds up subsequent executions. There is no need to reparse the statement or allocate memory for an Oracle private SQL area.
For inline use with implicit cursors, set HOLD_CURSOR before executing the SQL statement. For inline use with explicit cursors, set HOLD_CURSOR before CLOSEing the cursor.
Note that RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES and that HOLD_CURSOR=NO overrides RELEASE_CURSOR=NO. For information showing how these two options interact, see Table C - 1.
You can omit the filename extension if is .pc. If the input filename is the first option on the command line, you can omit the INAME= part of the option. For example:
proc sample1 MODE=ansi
to precompile the file sample1.pc, using ANSI mode. This command is the same as
proc INAME=sample1 MODE=ansi
You use INCLUDE to specify a directory path for included files. The precompiler searches directories in the following order:
Note: If you specify a filename without an extension for inclusion, Pro*C assumes an extension of .h. So, files to be included should have an extension, even if it is not .h.
You must still use INCLUDE to specify a directory path for nonstandard files unless they are stored in the current directory. You can specify more than one path on the command line, as follows:
... INCLUDE=<path_1> INCLUDE=<path_2> ...
The precompiler searches first in the current directory, then in the directory for standard header files, and finally in the directory named by path1, then in the directory named by path2.
Warning: The precompiler looks for a file in the current directory first--even if you specify a directory path. So, if the file you want to include resides in another directory, make sure no file with the same name resides in the current directory.
The syntax for specifying a directory path using the INCLUDE option is system specific. Follow the conventions used for your operating system.
The LINES option helps with debugging. When LINES=YES, the Pro*C precompiler adds #line preprocessor directives to its output file.
Normally, your C compiler increments its line count after each input line is processed. The #line directives force the compiler to reset its input line counter so that lines of precompiler-generated code are not counted. Moreover, when the name of the input file changes, the next #line directive specifies the new filename.
The C compiler uses the line numbers and filenames to show the location of errors. Thus, error messages issued by the C compiler always refer to your original source files, not the modified source file.
When LINES=NO (the default), the precompiler adds no #line directives to its output file.
Note: On page 3 - 3, it is stated that the Pro*C precompiler does not support the #line directive. This means that you cannot directly code #line directives in the precompiler source. But you can still use the LINES= option to have the precompiler insert #line directives for you.
The default filename extension for the listing file is .lis.
When a listing file is generated, the LONG format is the default. With LTYPE=LONG specified, all of the source code is listed as it is parsed and messages listed as they are generated. In addition, the Pro*C/C++ currently in effect are listed.
With LTYPE=SHORT specified, only the generated messages are listed--no source code--with line references to the source file to help you locate the code that generated the message condition.
With LTYPE=NONE specified, no list file is produced unless the LNAME option explicitly specifies a name for a list file. Under the latter condition, the list file is generated with LTYPE=LONG assumed.
The maximum value of MAXLITERAL is compiler dependent. For example, some C compilers cannot handle string literals longer than 512 characters, so you would specify MAXLITERAL=512.
Strings that exceed the length specified by MAXLITERAL are divided during precompilation, then recombined (concatenated) at run time.
You can use MAXOPENCURSORS to improve the performance of your program. For more information, see Appendix C.
When precompiling separately, use MAXOPENCURSORS as described in "Guidelines for Precompiling Separately" .
MAXOPENCURSORS specifies the initial size of the SQLLIB cursor cache. If a new cursor is needed, and there are no free cache entries, Oracle tries to reuse an entry. Its success depends on the values of HOLD_CURSOR and RELEASE_CURSOR, and, for explicit cursors, on the status of the cursor itself. Oracle allocates an additional cache entry if it cannot find one to reuse.
If necessary, Oracle keeps allocating additional cache entries until it runs out of memory or reaches the limit set by OPEN_CURSORS. MAXOPENCURSORS must be lower than OPEN_CURSORS by at least 6 to avoid a "maximum open cursors exceeded" Oracle error.
As your program's need for concurrently open cursors grows, you might want to respecify MAXOPENCURSORS to match the need. A value of 45 to 50 is not uncommon, but remember that each cursor requires another private SQL area in the user process memory space. The default value of 10 is adequate for most programs.
ISO is a synonym for ANSI.
When MODE=ORACLE (the default), your embedded SQL program observes Oracle practices. When MODE=ANSI, your program complies fully with the ANSI SQL standard, and the following changes go into effect:
This option allows you to specify at precompile time a list of the names of one or more host variables that the precompiler must treat as National Language character variables. You can specify only C char variables or Pro*C/C++ VARCHARs using this option.
If a you specify in the option list a variable that is not declared in your program, then the precompiler generates no error.
When NLS_LOCAL=YES, the runtime library (SQLLIB) performs blank-padding and blank-stripping for host variables that are National Language Support (NLS) multi-byte types.
When NLS_LOCAL=NO, the Oracle Server performs these actions.
When you use the NLS_CHAR option to specify multi-byte character host variables, you must specify NLS_LOCAL=YES.
proc iname=my_test
the default output filename is my_test.c. If you want the output filename to be my_test_1.c, issue the command
proc iname=my_test oname=my_test_1.c
Note that you should add the .c extension to files specified using ONAME.
The default extension with the ONAME option is platform-specific, but you can override it using the CODE and CPP_SUFFIX options. When CODE=KR_C or ANSI_C, the extension is c. When CODE=CPP, you can use the CPP_SUFFIX option to override the platform-specific default.
Attention: Oracle recommends that you not let the output filename default, but rather name it explicitly using ONAME.
When ORACA=YES, you must place either the EXEC SQL INCLUDE ORACA or #include oraca.h statement in your program.
See page 6 - 5 for more information on the PARSE option.
With PARSE=FULL or PARSE=PARTIAL Pro*C/C++ fully supports C preprocessor directives, such as #define, #ifdef, and so on. However, with PARSE=NONE conditional preprocessing is supported by EXEC ORACLE statements as described in "Conditional Preprocessing" .
You can use RELEASE_CURSOR to improve the performance of your program. For more information, see Appendix C.
When a SQL data manipulation statement is executed, its associated cursor is linked to an entry in the cursor cache. The cursor cache entry is in turn linked to an Oracle private SQL area, which stores information needed to process the statement. RELEASE_CURSOR controls what happens to the link between the cursor cache and private SQL area.
When RELEASE_CURSOR=YES, after Oracle executes the SQL statement and the cursor is closed, the precompiler immediately removes the link. This frees memory allocated to the private SQL area and releases parse locks. To make sure that associated resources are freed when you CLOSE a cursor, you must specify RELEASE_CURSOR=YES.
When RELEASE_CURSOR=NO and HOLD_CURSOR=YES, the link is maintained. The precompiler does not reuse the link unless the number of open cursors exceeds the value of MAXOPENCURSORS. This is useful for SQL statements that are executed often because it speeds up subsequent executions. There is no need to reparse the statement or allocate memory for an Oracle private SQL area.
For inline use with implicit cursors, set RELEASE_CURSOR before executing the SQL statement. For inline use with explicit cursors, set RELEASE_CURSOR before CLOSEing the cursor.
Note that RELEASE_CURSOR=YES overrides HOLD_CURSOR=YES and that HOLD_CURSOR=NO overrides RELEASE_CURSOR=NO. For a table showing how these two options interact, see Appendix C.
When SELECT_ERROR=YES, an error is generated when a single-row SELECT returns too many rows, or when an array SELECT returns more rows than the host array can accommodate. The result of the SELECT is indeterminate.
When SELECT_ERROR=NO, no error is generated when a single-row SELECT returns too many rows, or when an array SELECT returns more rows than the host array can accommodate.
Whether you specify YES or NO, a random row is selected from the table. The only way to ensure a specific ordering of rows is to use the ORDER BY clause in your SELECT statement. When SELECT_ERROR=NO and you use ORDER BY, Oracle returns the first row, or the first n rows when you are SELECTing into an array. When SELECT_ERROR=YES, whether or not you use ORDER BY, an error is generated when too many rows are returned.
The Pro*C precompiler can help you debug a program by checking the syntax and semantics of embedded SQL statements and PL/SQL blocks. You control the level of checking by entering the SQLCHECK option inline and/or on the command line. However, the level of checking you specify inline cannot be higher than the level you specify (or accept by default) on the command line. For example, if you specify SQLCHECK=SYNTAX on the command line, you cannot specify SQLCHECK=SEMANTICS inline.
SQLCHECK=SEMANTICS|FULL The precompiler checks the syntax and semantics of
Any errors found are reported at precompile time.
The precompiler gets information needed for a semantic check by using embedded DECLARE TABLE statements, or if you specify the USERID option on the command line, by connecting to Oracle and accessing the data dictionary. You need not connect to Oracle if every table referenced in a data manipulation statement or PL/SQL block is defined in a DECLARE TABLE statement.
If you connect to Oracle, but some needed information cannot be found in the data dictionary, you must use DECLARE TABLE statements to supply the missing information. A DECLARE TABLE definition overrides a data dictionary definition if they conflict.
If you embed PL/SQL blocks in a host program, you must specify SQLCHECK=SEMANTICS and the USERID option as well.
SQLCHECK=SYNTAX|LIMITED|NONE The precompiler checks the syntax of
But no semantic checking is done. DECLARE TABLE statements are ignored, and PL/SQL blocks are not allowed.
Specifying the SYNTAX value generates a useable output (code) file, however semantic errors can still occur at runtime.
But C++ compilers can have system header files, such as stdio.h, that are not in the standard system locations. You can use the SYS_INCLUDE command line option to specify a list of directory paths that Pro*C searches to look for system header files. For example
SYS_INCLUDE=(/usr/lang/SC2.0.1/include,/usr/lang/SC2.1.1/include)
The search path that you specify using SYS_INCLUDE overrides the default header location
If PARSE=NONE, the value specified in SYS_INCLUDE is irrelevant, since there is no need for Pro*C to include system header files. (You must, of course, still include Pro*C-specific headers, such sqlca.h.)
The precompiler searches directories in the following order:
The UNSAFE_NULL=YES is allowed only when MODE=ORACLE and DBMS=V7 or V6_CHAR.
The UNSAFE_NULL option has no effect on host variables in an embedded PL/SQL block. You must use indicator variables to avoid ORA-01405 errors.
Do not specify this option when using the automatic connect feature, which accepts your Oracle username prefixed with OPS$. The actual value of the "OPS$" string is set as a parameter in the INIT.ORA file.
When SQLCHECK=SEMANTICS, if you want the precompiler to get needed information by connecting to Oracle and accessing the data dictionary, you must also specify USERID.
This precompiler option is required for any program that requires multi-threaded support.
With THREADS=YES, the precompiler generates an error if no EXEC SQL USE directive is encountered before the first context is visible and an executable SQL statement is found. For more information, see "Developing Multi-threaded Applications" .
When VARCHAR=YES, a C struct that you code as
struct { short <len>; char <arr>[n]; } name;
is interpreted by the precompiler as a VARCHAR[n] host variable.
With Oracle7 and Pro*C Release 1.5 or later, private SQL areas are automatically resized, host variables are rebound only when necessary, and reentrant code is generated automatically for systems that require it. These advances make the AREASIZE, REBIND, and REENTRANT options obsolete. You no longer have to worry about using these options correctly. In fact, if you specify AREASIZE, REBIND, or REENTRANT, you get the following informational message:
PCC-I-02355: Invalid or obsolete option, ignored
Conditional sections of code are marked by statements that define the environment and actions to take. You can code C statements as well as EXEC SQL statements in these sections. The following statements let you exercise conditional control over precompilation:
EXEC ORACLE DEFINE symbol; -- define a symbol EXEC ORACLE IFDEF symbol; -- if symbol is defined EXEC ORACLE IFNDEF symbol; -- if symbol is not defined EXEC ORACLE ELSE; -- otherwise EXEC ORACLE ENDIF; -- end this control block
All EXEC ORACLE statements must be terminated with a semi-colon.
EXEC ORACLE DEFINE symbol;
in your host program or define the symbol on the command line using the syntax
... INAME=filename ... DEFINE=symbol
where symbol is not case-sensitive.
Warning: The #define preprocesssor directive is not the same as the EXEC ORACLE DEFINE command
Some port-specific symbols are predefined for you when the Pro*C Precompiler is installed on your system. For example, predefined operating system symbols include CMS, MVS, MS-DOS, UNIX, and VMS.
EXEC ORACLE IFDEF site2; EXEC SQL SELECT DNAME INTO :dept_name FROM DEPT WHERE DEPTNO = :dept_number; EXEC ORACLE ENDIF;
Blocks of conditions can be nested as shown in the following example:
EXEC ORACLE IFDEF outer; EXEC ORACLE IFDEF inner; ... EXEC ORACLE ENDIF; EXEC ORACLE ENDIF;
You can "comment out" C or embedded SQL code by placing it between IFDEF and ENDIF and not defining the symbol.
#define SQLCA_STORAGE_CLASS extern
which tell the precompiler to look for the SQLCA in another program module. Unless you declare the SQLCA as external, each program module uses its own local SQLCA.
The linker resolves symbolic references in the object modules. If these references conflict, the link fails. This can happen when you try to link third-party software into a precompiled program. Not all third-party software is compatible with Oracle. So, linking your program shared might cause an obscure problem. In some cases, linking stand-alone or two-task might solve the problem.
Compiling and linking are system dependent. On most platforms, example makefiles or batch files are supplied that you can use to precompile, compile, and link a Pro*C application. See your system-specific Oracle documentation.
![]() ![]() Prev Next |
![]() Copyright © 1997 Oracle Corporation. All Rights Reserved. |
![]() Library |
![]() Product |
![]() Contents |
![]() Index |