Introduction To Pro - C
Introduction To Pro - C
Resources
Database
Systems: The Complete Book by Hector Garcia, Jeff Ullman, and
Jennifer
Widom.
A
First Course in Database Systems by Jeff Ullman and Jennifer Widom.
Gradiance SQL
Tutorial.
Introduction to Pro*C
Embedded SQL
Overview
Pro*C Syntax
SQL
Preprocessor Directives
Statement Labels
Host Variables
Basics
Pointers
Structures
Arrays
Indicator Variables
Datatype Equivalencing
Dynamic SQL
Transactions
Error Handling
SQLCA
WHENEVER Statement
Demo Programs
C++ Users
List of Embedded
SQL Statements Supported by Pro*C
Overview
Embedded SQL is a method of combining the computing power of a high-level
language like C/C++ and the database manipulation capabilities of SQL.
It allows you
to execute any SQL statement from an application program.
Oracle's embedded SQL
environment is called Pro*C.
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 1/15
8/28/2021 Introduction to Pro*C
Pro*C Syntax
SQL
All SQL statements need to start with EXEC SQL and end with a
semicolon ";". You can
place the SQL statements anywhere within
a C/C++ block, with the restriction that the
declarative statements do
not come after the executable statements. As an example:
{
int a;
/* ... */
/* ... */
/* ... */
}
Preprocessor
Directives
The C/C++ preprocessor directives that work with Pro*C are #include
and #if. Pro*C
does not recognize #define. For example,
the following code is invalid:
#define THE_SSN 876543210
/* ... */
Statement Labels
/* ... */
error_in_SQL:
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 2/15
8/28/2021 Introduction to Pro*C
Host Variables
Basics
Host variables are the key to the communication between the host program
and the
database. A host variable expression must resolve to an lvalue
(i.e., it can be assigned).
You can declare host variables according
to C syntax, as you declare regular C
variables. The host variable declarations
can be placed wherever C variable
declarations can be placed. (C++ users
need to use a declare section; see the section on
C++
Users.) The C datatypes that can be used with Oracle include:
char
char[n]
int
short
long
float
double
VARCHAR[n] - This is a psuedo-type recognized
by the Pro*C precompiler. It is
used to represent blank-padded, variable-length
strings. Pro*C precompiler will
convert it into a structure with a 2-byte
length field and a n-byte character array.
int main() {
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 3/15
8/28/2021 Introduction to Pro*C
lvalue */
Pointers
You can define pointers using the regular C syntax, and use them in embedded
SQL
statements. As usual, prefix them with a colon:
int *x;
/* ... */
Structures
char name[21]; /* one greater than column length; for '\0' */
} Emp;
/* ... */
/* ... */
Arrays
/* ... */
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 4/15
8/28/2021 Introduction to Pro*C
When using arrays to store the results of a query, if the size of the
host array (say n) is
smaller than the actual number of tuples returned
by the query, then only the first n
result tuples will be entered
into the host array.
Indicator
Variables
/* ... */
You can also use indicator variables in the VALUES and SET
clause of an INSERT or
UPDATE statement to assign
NULL's
to input host variables. The values your program can
assign to an indicator
variable have the following meanings:
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 5/15
8/28/2021 Introduction to Pro*C
Datatype
Equivalencing
For example, suppose you want to select employee names from the emp
table, and then
pass them to a routine that expects C-style '\0'-terminated
strings. You need not
explicitly '\0'-terminate the names yourself.
Simply equivalence a host variable to the
STRING external datatype,
as follows:
/* ... */
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 6/15
8/28/2021 Introduction to Pro*C
Here we allocated more memory than the type length (4000) because the precompiler
also returns the length, and may add padding after the length in order
to meet the
alignment requirement on your system.
Dynamic SQL
While embedded SQL is fine for fixed applications, sometimes it is important
for a
program to dynamically create entire SQL statements. With dynamic
SQL, a statement
stored in a string variable can be issued. PREPARE
turns a character string into a SQL
statement, and
EXECUTE executes
that statement. Consider the following example.
char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)";
TransactionsOracle
PRO*C supports transactions as defined by the SQL standard. A
transaction
is a sequence of SQL statements that Oracle treats as a single unit of
work.
A transaction begins at your first SQL statement. A transaction ends
when you issue
"EXEC SQL COMMIT" (to make permanent any database
changes during the current
transaction) or "EXEC SQL ROLLBACK"
(to undo any changes since the current transaction
began). After the current
transaction ends with your
COMMIT or ROLLBACK statement,
the
next executable SQL statement will automatically begin a new transaction.
Error HandlingAfter
each executable SQL statement, your program can find the
status of execution
either by explicit checking of SQLCA, or by implicit checking
using the
WHENEVER
statement. These two ways are covered in details below.
SQLCA
SQLCA (SQL Communications Area) is used to detect errors and status changes
in
your program. This structure contains components that are filled in
by Oracle at
runtime after every executable SQL statement.
To use SQLCA you need to include the header file sqlca.h using
the #include
directive. In case you need to include sqlca.h
at many places, you need to first
undefine the macro SQLCA with
#undef
SQLCA. The relevant chunk of sqlca.h follows:
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 7/15
8/28/2021 Introduction to Pro*C
#ifndef SQLCA
#define SQLCA 1
struct sqlca {
} sqlerrm;
};
/* ... */
sqlcaid This string component is initialized to "SQLCA" to identify the SQL
Communications Area.
sqlcabc This integer component holds the length, in bytes, of the SQLCA structure.
sqlcode This integer component holds the status code of the most recently executed
SQL statement:
0 No error.
Statement executed but exception detected. This occurs when
>0 Oracle
cannot find a row that meets your WHERE condition or
when a SELECT
INTO or FETCH returns no rows.
Oracle did not execute the statement because of an error. When
<0 such
errors occur, the current transaction should, in most cases,
be rolled
back.
sqlerrm This embedded structure contains the following two components:
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 8/15
8/28/2021 Introduction to Pro*C
sqlwarn This array of single characters has eight elements used as warning
flags.
Oracle sets a flag by assigning to it the character 'W'.
sqlwarn[0] Set if any other flag is set.
Set if a truncated column value was assigned to an
sqlwarn[1]
output host variable.
Set if a NULL column value is not used in computing a
sqlwarn[2]
SQL
aggregate such as AVG or SUM.
Set if the number of columns in SELECT does not equal
sqlwarn[3]
the
number of host variables specified in INTO.
Set if every row in a table was processed by an UPDATE
sqlwarn[4]
or
DELETE
statement without a WHERE clause.
Set if a procedure/function/package/package body
sqlwarn[5] creation command fails
because of a PL/SQL
compilation error.
sqlwarn[6] No longer in use.
sqlwarn[7] No longer in use.
sqlext Reserved for future use.
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 9/15
8/28/2021 Introduction to Pro*C
WHENEVER Statement
CONTINUE - Program will try to continue to run with the next statement
if possible
DO - Program transfers control to an error handling function
GOTO <label> - Program branches to a labeled statement
STOP - Program exits with an exit() call, and uncommitted
work is rolled back
/* ... */
for (;;) {
continue;
notfound:
/* ... */
Note that the WHENEVER statement does not follow regular C scoping rules.
Scoping
is valid for the entire program. For example, if you have
the following statement
somewhere in your program (such as before a loop):
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 10/15
8/28/2021 Introduction to Pro*C
All SQL statements that occur after this line in the file would be affected.
Make sure
you use the following line to cancel the effect of WHENEVER when
it is no longer
needed (such as after your loop):
Demo Programs
Note: The demo programs will create and use four tables named DEPT,
EMP,
PAY1,
and
PAY2. Be careful if any table in your database happens to
have the same name!
Step (2) will set up the sample database, create a new directory as specified
in
<sample_dir>, and copy the demo files into that directory.
It will also change the user
name and password in the sample programs to
be yours, so that you do not have to type
in your username and password
every time when running a sample program. However,
sample1 and
cppdemo1
do provide an interface for the user to input the username and
password,
in case you would like to learn how to do it.
For Step (4), you can also compile each sample program separately. For
example, make
sample1 compiles sample1.pc alone. The
compilation process actually has two phases:
1. proc iname=sample1.pc
converts the embedded SQL code to corresponding library calls and outputs
sample1.c
2. cc <a_number_of_flags_here> sample1.c
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 11/15
8/28/2021 Introduction to Pro*C
To compile your own code, say, foo.pc, just change a few variables
in Makefile: Add
the program name foo to variable SAMPLES
and the source file name foo.pc to variable
SAMPLE_SRC.
Then, do make foo after foo.pc is ready. foo.pc
will be precompiled to
foo.c and then compiled to foo,
the executable. C++ users will need to add their
program name to CPPSAMPLES
instead of SAMPLES, and source file name to
CPPSAMPLE_SRC
instead of SAMPLE_SRC.
You should take a look at the sample source code before running it.
The comments at
the top describe what the program does. For example, sample1
takes an employee's
EMPNO and retrieve the name, salary, and commission
for that employee from the table
EMP.
You are supposed to study the sample source code and learn the following:
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 12/15
8/28/2021 Introduction to Pro*C
Now, you can use these techniques to code your own database application
program.
And have fun!
C++ Users
To get the precompiler to generate appropriate C++ code, you need to be
aware of the
following issues:
Code emission by precompiler. To get C++ code, you need to set the option
CODE=CPP
while executing proc. C users need not worry about this option;
the
default caters to their needs.
// declarations...
EXEC SQL END DECLARE SECTION;
You need to follow this routine for declaring the host and indicator variables
at all
the places you do so.
List
of Embedded SQL Statements Supported by Pro*C
Declarative Statements
EXEC SQL ARRAYLEN To use host arrays with PL/SQL
EXEC SQL BEGIN DECLARE SECTION
To embed PL/SQL blocks
END-EXEC
infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html 15/15