#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Include the SQL Communications Area, a structure through
* which ORACLE makes runtime status information such
as error
* codes, warning flags, and diagnostic text available
to the
* program.
*/
#include <sqlca.h>
/* Include the ORACLE Communications Area, a structure
through
* which ORACLE makes additional runtime status information
* available to the program.
*/
#include <oraca.h>
/* The ORACA=YES option must be specified to enable you
* to use the ORACA.
*/
EXEC ORACLE OPTION (ORACA=YES);
/* Specifying the RELEASE_CURSOR=YES option instructs
Pro*C
* to release resources associated with embedded SQL
* statements after they are executed. This ensures that
* ORACLE does not keep parse locks on tables after data
* manipulation operations, so that subsequent data definition
* operations on those tables do not result in a parse-lock
* error.
*/
EXEC ORACLE OPTION (RELEASE_CURSOR=YES);
void sql_error()
{
/* This is the Oracle error handler.
* Print diagnostic text containing the error message,
* current SQL statement, and location of error.
*/
printf("\n%.*s\n",
sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
printf("in \"%.*s...\"\n",
oraca.orastxt.orastxtl, oraca.orastxt.orastxtc);
printf("on line %d of %.*s.\n\n",
oraca.oraslnr, oraca.orasfnm.orasfnml,
oraca.orasfnm.orasfnmc);
/* Disable Oracle error checking to avoid an infinite
loop
* should another error occur within this routine as a
* result of the rollback.
*/
EXEC SQL WHENEVER SQLERROR CONTINUE;
/* Roll back any pending changes and disconnect from Oracle.
*/
EXEC SQL ROLLBACK RELEASE;
exit(1);
}
typedef char asciz[80];
EXEC SQL TYPE asciz IS STRING(80) REFERENCE;
void main()
{
/* Declare the program host variables. */
char *username = "SCOTT";
char *password = "TIGER";
asciz dynstmt1;
char dynstmt2[10];
VARCHAR dynstmt3[80];
/* Call routine sql_error() if an ORACLE error occurs. */
EXEC SQL WHENEVER SQLERROR DO sql_error();
/* Save text of current SQL statement in the ORACA if
an
* error occurs.
*/
oraca.orastxtf = ORASTFERR;
/* Connect to Oracle. */
EXEC SQL CONNECT :username IDENTIFIED BY :password;
puts("\nConnected to ORACLE.\n");
/* Execute a string literal to create the table. This
* usage is actually not dynamic because the program does
* not determine the SQL statement at run time.
*/
puts("CREATE TABLE dyn1 (col1 VARCHAR2(4))");
EXEC SQL EXECUTE IMMEDIATE
"CREATE TABLE dyn1 (col1 VARCHAR2(4))";
/* Execute a string to insert a row. The string must
* be null-terminated. This usage is dynamic because the
* SQL statement is a string variable whose contents the
* program can determine at run time.
*/
strcpy((char *)dynstmt1, "INSERT INTO DYN1 values ('TEST')");
puts(dynstmt1);
EXEC SQL EXECUTE IMMEDIATE :dynstmt1;
/* Execute a SQL statement in a string to commit the insert.
* Pad the unused trailing portion of the array with spaces.
* Do NOT null-terminate it.
*/
strcpy(dynstmt2, "COMMIT ");
printf("%.10s\n", dynstmt2);
EXEC SQL EXECUTE IMMEDIATE :dynstmt2;
/* Execute a VARCHAR to drop the table. Set the .len field
* to the length of the .arr field.
*/
strcpy((char *)dynstmt3.arr, "DROP TABLE DYN1");
dynstmt3.len = (unsigned short)strlen((char *)dynstmt3.arr);
puts((char *) dynstmt3.arr);
EXEC SQL EXECUTE IMMEDIATE :dynstmt3;
/* Commit any outstanding changes and disconnect from
Oracle. */
EXEC SQL COMMIT RELEASE;
puts("\nHave a good day!\n");
exit(0);
}