Appendix B. Porting Pro*C Applications to APRE#
Refer to this appendix when converting an application that was written using Oracle Pro*C/C++ so that it can be compiled using the Altibase C/C++ Precompiler.
Datatypes#
This section describes the Oracle data types and the corresponding data types of Altibase.
ODBC SQL data type | Oracle | Altibase | Remarks |
---|---|---|---|
SQL_CHAR | CHAR | CHAR | 1-32000 length |
SQL_TIMESTAMP | DATE | DATE | |
SQL_LONGVARCHAR | LONG | BLOB | Up to 2147483647bytes |
SQL_INTEGER | INT | INTEGER | |
SQL_FLOAT | NUMBER | NUMBER | |
SQL_DECIMAL | NUMBER(P) | NUMBER(P) | 1-38 |
SQL_DECIMAL | NUMBER(P,S) | NUMBER(P,S) | precision : 1-38 scale : -84 - 126 |
SQL_BINARY | RAW | HSS_BYTES | 1-32000 |
SQL_VARCHAR | VARCHAR | VARCHAR | max 32000 bytes |
SQL_VARCHAR | VARCHAR2 | VARCHAR | max 32000 bytes |
Embedded Functions#
Like Oracle, Altibase provides numeric functions, date functions, string functions, data type conversion functions, and other built-in functions. This section explains which Altibase functions should be used in place of corresponding Oracle functions.
The name, purpose, and method of use of each built-in function of Altibase is similar to its counterpart in Oracle.
The following built-in functions are supported in Altibase:
- Numeric Functions:
ABS, ACOS, ASIN, ATAN, ATAN2, CEIL, COS, COSH, EXP, FLOOR, ISNUMERIC, LN, LOG, MOD, POWER, RANDOM, ROUND, SIGN, SIN, SINH, SQRT, TAN, TANH, TRUNC, BITTAND, BITOR, BITXOR, BITNOT - Aggregate Functions:
AVG, COUNT, GROUP_CONCAT, LISTAGG, MAX, MIN, PERCENTILE_CONT, PERCENTILE_DISC, STATS_ONE_WAY_ANOVA, STDDEV, STDDEV_POP, STDDEV_SAMP, SUM, VARIANCE, VAR_POP, VAR_SAMP - Character Functions:
ASCII, CHAR_LENGTH, CHOSUNG, CHR, CONCAT, DIGITS, INITCAP, INSTR, INSTRB, POSITION, LOWER, LPAD, LTRIM, NCHR, OCTET_LENGTH, PKCS7PAD16, PKCS7UNPAD16, RANDOM_STRING, REGEXP_COUNT, REGEXP_INSTR, REGEXP_SUBSTR, REPLACE2, REVERSE_STR, RPAD, RTRIM, SIZEOF, SUBSTR, TRANSLATE, TRIM, UPPER, REPLICATE, REVERSE_STR, STUFF, UPPER - Date/time Functions:
ADD_MONTHS, CURRENT_DATE, CURRENT_TIMESTAMP, CONV_TIMEZONE, DATEADD, DATEDIFF, DATENAME, DB_TIMEZONE, EXTRACT, LAST_DAY, MONTHS_BETWEEN, ROUND, NEXT_DAY, SESSION_TIMEZONE, SYSDATE, SYSTIMESTAMP, TRUNC, UNIX_DATE, UNIX_TIMESTAMP - Data Type Conversion Functions:
ASCIISTR, BIN_TO_NUM, CONVERT, DATE_TO_UNIX, HEX_ENCODE, HEX_DECODE, HEX_TO_NUM, OCT_TO_NUM, TO_BIN, TO_CHAR, TO_DATE, TO_HEX, TO_NCHAR, TO_NUMBER, TO_OCT, TO_RAW, UNISTR, UNIX_TO_DATE - Encryption Functions:
AESDECRYPT, AESENCRYPT, DESENCRYPT, DESDECRYPT, TDESDECRYPT/TRIPLE_DESDECRYPT,TDESENCRYPT/TRIPLE_DESENCRYPT - Window Functions: AVG, COUNT, LISTAGG, MAX, MIN, PERCENTILE_CONT, AVG, COUNT, LISTAGG, MAX, MIN, PERCENTILE_CONT, PERCENTILE_DISC, STDDEV, SUM, VARIANCE, GROUP_CONCAT, RANK, DENSE_RANK, ROW_NUMBER, LAG, LEAD, FIRST_VALUE, LAST_VALUE, NTH_VALUE
- Miscellaneous Functions:
BINARY_LENGTH, CASE2, CASE_WHEN, COALESCE, DECODE, DIGEST, DUMP, GREATEST, GROUPING, GROUPING_ID, HOST_NAME, LEAST, LNNVL, NULLIF, NVL, NVL2, RAW_SIZEOF, RAW_CONCAT, ROWNUM, NVL, NVL2, SENDMSG, SUBRAW, SYS_CONNECT_BY_PATH, USER_ID, USER_NAME, SESSION_ID
For more information, please refer to the SQL Reference.
Managing Database Connections#
This chapter describes the differences in the database connection and disconnection methods between Oracle and Altibase.
Connecting to a Database#
The command that is used to establish a default connection is the same in Oracle and Altibase. Oracle and Altibase are also similar in that multiple connections can be established if names are assigned to individual connections, and in that connection options can be set using the USING clause.
Connect Statement#
-
Oracle
EXEC SQL CONNECT {:user IDENTIFIED BY :oldpswd :usr_psw } [[ AT { dbname | :host_variable }] USING :connect_string ];
-
Altibase
EXEC SQL [AT {conn_name | :conn_name}] CONNECT <:user> IDENTIFIED BY <:passwd> [USING <:conn_opt>[,<:conn_opt2>]];
Establishing the Default Connection#
-
Oracle
char *username = "SCOTT"; char *password = "TIGER"; char *connstr = "ORA817"; EXEC SQL WHENEVER SQLERROR . . . EXEC SQL CONNECT :username IDENTIFIED BY :password USING :connstr;
-
Altibase
strcpy(username, "SYS"); strcpy(password, "MANAGER"); strcpy(connstr,"DSN=192.168.1.2;PORTNO=20310;CONNTYPE=3"); EXEC SQL CONNECT :username IDENTIFIED BY :password USING :connstr;
-
If the USING clause is not specified, the application will attempt to connect to an Altibase database on the same system.
Establishing a Named Connection#
-
Oracle
char *username = "SCOTT"; char *password = "TIGER"; char *connstr = "ORA817"; EXEC SQL WHENEVER SQLERROR . . . EXEC SQL CONNECT :username IDENTIFIED BY :password AT :db_name USING :connstr;
-
Altibase
strcpy(user2, "ALTIBASE"); strcpy(passwd2, "ALTIBASE"); strcpy(conn_name, "CONN2"); strcpy(connstr,"DSN=192.168.1.12;PORTNO=20310;CONNTYPE=1"); EXEC SQL AT :conn_name CONNECT :user2 IDENTIFIED BY :passwd2 USING :connstr;
Disconnecting from a Database#
In Oracle, the EXEC SQL ROLLBACK WORK RELEASE statement is used to roll back any pending transactions and disconnect from the database in a single line of code.
This statement is also supported in Altibase.
Disconnect Statement#
-
Oracle
orEXEC SQL COMMIT WORK RELEASE;
EXEC SQL ROLLBACK WORK RELEASE;
-
Altibase
orEXEC SQL COMMIT WORK RELEASE;
EXEC SQL ROLLBACK WORK RELEASE;
Host Variables#
This section describes the differences between the host variables used with Oracle Pro*C and those used with the Altibase C/C++ Precompiler.
Host Variable Compatibility#
Oracle | Altibase | Remarks | ||
---|---|---|---|---|
Database Column type | Host Variable C type | Database Column type | Host Variable C type | |
CHAR | char | CHAR | char/char[2] | single character |
VARCHAR2(X) VARCHAR(X) | VARCHAR[X] | VARCHAR | VARCHAR | n-byte variable-length character array |
CHAR[X] | char[x] | CHAR[X] | char[x] | n-byte character array |
NUMBER | int | NUMBER/ INTEGER | int/ APRE _INT | integer |
NUMBER(P,S) | short int long float double | NUMBER(P,S) | short int/APRE_INTEGER long float double | small integer integer large integer float-point number double-precision floating-point number |
DATE | char[n] varchar[n] | DATE | char[n] varchar[n] | n >= 20 |
Host Variable Declaration Section#
The statements used to delimit the host variable declaration section are the same in Altibase and Oracle.
-
Oracle
EXEC SQL BEGIN DECLARE SECTION; /* Host variable declaration */ EXEC SQL END DECLARE SECTION;
-
Altibase
EXEC SQL BEGIN DECLARE SECTION; /* Host variable declaration */ EXEC SQL END DECLARE SECTION;
Using Embedded SQL Statements#
This section compares the use of basic SQL statements (SELECT, UPDATE, INSERT, DELETE), cursor control SQL statements and dynamic SQL statements in Oracle Pro*C and the Altibase C/C++ Precompiler
Basic DML Statements#
Basic DML statements, for example the SELECT, INSERT, UPDATE, and DELETE statements, are executed the same way (i.e. using EXEC SQL) in both Oracle and Altibase.
Cursor Control SQL Statements#
The fundamental method of declaring cursors is the same in Oracle and Altibase. They only differ in that Oracle supports the declaration of cursor variables in the host variable declaration section, just like host variables, whereas Altibase does not.
Cursor Declaration#
-
Oracle
EXEC SQL DECLARE cur_emp CURSOR FOR SELECT ename, job, sal FROM emp;
-
Altibase
EXEC SQL DECLARE cur_emp CURSOR FOR SELECT ename, job, sal FROM emp;
Cursor Open and Fetch#
The methods used to open cursors and fetch records are the same in Altibase and Oracle.
However, the error code types and values differ between the two products, which means that error-handling code written inside the FETCH statement will need to be changed. The support for the use of the WHENEVER statement to handle runtime errors (e.g. EXEC SQL WHENEVER NOT FOUND DO BREAK;) is the same in Altibase as it is in Oracle.
-
Oracle
EXEC SQL OPEN cur_emp; if(sqlca.sqlcode != SQL_OK ) { fprintf(stderr, "OPEN CSR ERROR%d\n",sqlca.sqlcode); close_db(); exit(0); } for(;;) { EXEC SQL FETCH cur_emp INTO :emp_name, :job_title, :salary; switch(sqlca.sqlcode) { case 0: printf("emp_name : %s\n", emp_name); continue; case 1403: /* Not Found Data */ break; default : fprintf(stderr, "FETCH CSR ERROR %d",sqlca.sqlcode); close_db(); exit(0); } }
-
Altibase
EXEC SQL OPEN cur_emp; if(sqlca.sqlcode != SQL_SUCCESS ) { fprintf(stderr, "OPEN CSR ERROR %d\n",sqlca.sqlcode); close_db(); exit(0); } for(;;) { EXEC SQL FETCH cur_emp INTO :emp_name, :job_title, :salary; switch(sqlca.sqlcode) { case SQL_SUCCESS: printf("emp_name : %s\n", emp_name); continue; case SQL_NO_DATA: /* Not Found Data */ break; default : fprintf(stderr, "FETCH CSR ERROR %d",sqlca.sqlcode); close_db(); exit(0); } }
Closing Cursors#
The use of the CLOSE statement to close a cursor is the same in both Oracle Pro*C and APRE.
-
Oracle
EXEC SQL CLOSE cur_emp;
-
Altibase
EXEC SQL CLOSE cur_emp;
Dynamic SQL Statements#
Altibase supports Oracle Dynamic SQL Methods 1, 2, 3, and 4.
In Oracle, both the syntax ":v[1...n]" and the question mark ("?") can be used as parameter markers within embedded SQL statements. Altibase only supports the use of the question mark ("?").
Method 1#
-
Oracle
char dynstmt1[80]; strcpy(dynstmt1, "DROP TABLE EMP" ); EXEC SQL EXECUTE IMMEDIATE :dynstmt1;
-
Altibase
EXEC SQL BEGIN DECLARE SECTION; char dynstmt1[80]; EXEC SQL END DECLARE SECTION; strcpy(dynstmt1, "DROP TABLE EMP" ); EXEC SQL EXECUTE IMMEDIATE :dynstmt1;
Method 2#
-
Oralce
int emp_number; char delete_stmt[120]; . . . strcpy(delete_stmt, "DELETE FROM EMP WHERE EMPNO = :v1"); EXEC SQL PREPARE sql_stmt FROM :delete_stmt; emp_number = 10; EXEC SQL EXECUTE sql_stmt USING :emp_number;
-
Altibase
EXEC SQL BEGIN DECLARE SECTION; int emp_number; char delete_stmt[120]; EXEC SQL END DECLARE SECTION; . . . strcpy(delete_stmt, "DELETE FROM EMP WHERE EMPNO = ?"); EXEC SQL PREPARE sql_stmt FROM :delete_stmt; emp_number = 10; EXEC SQL EXECUTE sql_stmt USING :emp_number;
Method 3#
-
Oracle
char sql_query[80]; int deptno = 10; char ename[10]; strcpy(sql_query,"SELECT ename FROM emp WHERE deptno > :v1"); EXEC SQL PREPARE S FROM : sql_query; EXEC SQL DECLARE C CURSOR FOR S; EXEC SQL OPEN C USING :deptno; for (;;) { EXEC SQL FETCH C INTO :ename; . . . }
-
Altibase
EXEC SQL BEGIN DECLARE SECTION; char sql_query[80]; int deptno = 10; char ename[10]; EXEC SQL END DECLARE SECTION; strcpy(sql_query,"SELECT ename FROM emp WHERE deptno > ? "); EXEC SQL PREPARE S FROM : sql_query; EXEC SQL DECLARE C CURSOR FOR S; EXEC SQL OPEN C USING :deptno; for (;;) { EXEC SQL FETCH C INTO :ename; . . . }
Method 4#
-
Oracle
#define MAX_COLUMN_SIZE 30 char name[10]; int number; short ind_number; char *sql_stmt = "INSERT INTO emp (empno, ename) VALUES(:e, :n); SQLDA *binda; . . . binda = SQLSQLDAAlloc(SQL_SINGLE_RCTX, MAX_COLUMN_SIZE, 10, 10); binda->N = MAX_COLUMN_SIZE; EXEC SQL PREPARE stmt FROM :sql_stmt; EXEC SQL DESCRIBE BIND VARIABLES FOR stmt INTO binda; binda->N = binda->F; binda->V[0] = (char*)&number; binda->L[0] = (long)sizeof(int); binda->T[0] = 3; binda->I[0] = &ind_number; binda->V[1] = (char*) name; binda->L[1] = (long) 10; binda->T[1] = 1; binda->I[1] = (short*)0; . . . number = 1024; strcpy(name, "ALLISON"); ind_number = 0; EXECUTE stmt USING DESCRIPTOR binda;
-
Altibase
#define MAX_COLUMN_SIZE 30 EXEC SQL BEGIN DECLARE SECTION; char *sql_stmt = "INSERT INTO emp VALUES(?,?)"; SQLDA *binda; EXEC SQL END DECLARE SECTION; int number; char name[10]; short ind_name; binda = (SQLDA*) SQLSQLDAAlloc( MAX_COLUMN_SIZE ); EXEC SQL PREPARE stmt FROM :sql_stmt; EXEC SQL DESCRIBE BIND VARIABLES FOR stmt INTO :binda; binda->N = binda->F; binda->V[0] = (char*)&number; binda->L[0] = sizeof(int); bidna->T[0] = SQLDA_TYPE_SINT; binda->I[0] = NULL; binda->V[1] = (char*)name; binda->L[1] = 10; binda->T[1] = SQLDA_TYPE_CHAR; binda->I[1] = (short*)&ind_name; number = 1024; strcpy(name, "ALLISON"); ind_name = strlen(name); EXEC SQL EXECUTE stmt USING DESCRIPTOR :binda;
Execution Results and Status Codes#
This section will explain the differences between Oracle and Altibase in the use of the SQLSTATE, SQLCODE and SQLCA variables to handle runtime errors.
SQLCA#
SQLCA is a structure in which information about the results of execution of embedded SQL statements is saved. In Altibase, the supported elements of the structure are sqlcode, sqlerrm.sqlerrmc, sqlerrm.sqlerrml, sqlerrd[2] and sqlerrd[3]. Other SQLCA elements, such as sqlwarn, are implemented only in the Oracle SQLCA structure, and are not supported for use in Altibase.
SQLCA Declaration#
-
Oracle
orEXEC SQL INCLUDE SQLCA;
#include <sqlca.h>
-
Altibase
In APRE, this structure is defined by default, and does not have to be explicitly declared.
sqlca.sqlcode Status#
-
Oracle
Status Code Description 0 Success >0 No rows returned <0 database, system, network , application error -
Altibase
Status Code Description SQL_SUCCESS Success SQL_SUCCESS_WITH_INFO SQL_NO_DATA No rows returned SQL_ERROR SQL_INVALID_HANDLE
sqlca.sqlerrm#
sqlerrmc and sqlerrml are implemented identically in Oracle and Altibase.
sqlca.sqlerrd[2]#
-
Oracle
This element indicates the number of records that were affected by an INSERT, UPDATE, DELETE, or SELECT INTO operation. This number is cumulative. -
Altibase
Unlike Oracle, in Altibase the number stored in this element is not cumulative. When an INSERT, UPDATE, or DELETE operation is performed, this element indicates the number of records that were affected. When a SELECT or FETCH statement is executed using an array-type output host variable, this element indicates the number of records that were returned.
SQLSTATE#
SQLSTATE is used to store a status code, which is used to determine the kind of error or exception that has occurred.
Declaration and Use of SQLSTATE#
-
Oracle
In Oracle, SQLSTATE must be declared and the MODE=ANSI precompiler option must be specified when precompiling.char SQLSTATE[6];
-
Altibase
Can be used without declaration.
SQLSTATE Status Codes#
The values of the SQLSTATE status codes and their meanings in Oracle differ from the ODBC standard. Therefore, it will be necessary to appropriately convert SQLSTATE status codes to the ODBC equivalents with reference to Chapter 7: Status Codes and the ODBC code table.
SQLCODE#
SQLCODE is used to store error codes after the execution of an embedded SQL statement.
Declaring and Using SQLCODE#
-
Oracle
In Oracle, SQLCODE must be declared and the MODE=ANSI precompiler option must be specified when precompiling.long SQLCODE;
-
Altibase
Can be used without declaration
SQLCODE Status Code Values#
-
Oracle
The SQLCODE status codes are the same as for sqlca.sqlcode. -
Altibase
Status Code Description 0 Upon successful execution of the embedded SQL statement, that is, when the value of sqlca.sqlcode is SQL_SUCCESS 1 When the embedded SQL statement is executed successfully but a warning is detected, at which time the value of sqlca.sqlcode is SQL_SUCCESS_WITH_INFO 100 hen no records were returned as the result of execution of a SELECT or FETCH statement, that is, when the value of sqlca.sqlcode is SQL_NO_DATA -1 When an error occurred during the execution of an embedded SQL statement, but there is no error code corresponding to the error. At this time, the value of sqlca.sqlcode is SQL_ERROR. -2 WWhen an attempt was made to execute an embedded SQL statement without first establishing a database connection, that is, when the value of sqlca.sqlcode is SQL_INVALID_HANDLE - The presence of any value other than the values listed above in SQLCODE is an error message indicating the occurrence of an error in the corresponding SQL statement.
Commit Mode#
This section explains the differences between Altibase and Oracle related to the commit mode, including the default commit mode, how to change the commit mode, and how to commit transactions.
Default Commit Mode#
Oracle | Altibase |
---|---|
Non-Autocommit mode | Autocommit mode |
Changing the Commit Mode#
-
Oracle
orEXEC SQL ALTER SESSION SET AUTOCOMMIT = TRUE
EXEC SQL ALTER SESSION SET AUTOCOMMIT = FALSE
-
Altibase
orEXEC SQL AUTOCOMMIT ON
orEXEC SQL ALTER SESSION SET AUTOCOMMIT = TRUE
EXEC SQL ALTER SESSION SET AUTOCOMMIT = FALSE
Explicit Commit#
-
Oracle
orEXEC SQL COMMIT;
EXEC SQL COMMIT WORK;
-
Altibase
EXEC SQL COMMIT;
Sample Programs#
The following sample source code contains examples of the points described above.
Oracle#
#include <stdio.h>
#include <stdlib.h>
EXEC SQL include sqlca.h;
EXEC SQL BEGIN DECLARE SECTION;
char emp_name[21];
char job_title[21];
int salary;
int emp_number;
EXEC SQL END DECLARE SECTION;
char uid[10] = "SCOTT";
char pwd[10] = "TIGER";
int main(void)
{
int dynamic_emp_number;
char dynamic_stmt[120];
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;
if ( sqlca.sqlcode != 0 ) {
fprintf(stderr, "DataBase Connect Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
/* INSERT */
/* value setting */
emp_number = 10;
strcpy(emp_name, "oracle1");
strcpy(job_title, "oracle dba1");
salary = 10000;
/* INSERT DML */
EXEC SQL INSERT INTO emp (empno, ename, job, sal)
VALUES (:emp_number, :emp_name, :job_title, :salary);
if ( sqlca.sqlcode != 0 ) {
fprintf(stderr, "DataBase Connect Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
emp_number = 20;
strcpy(emp_name, "oracle2");
strcpy(job_title, "oracle dba2");
salary = 10000;
EXEC SQL INSERT INTO emp (empno, ename, job, sal)
VALUES (:emp_number, :emp_name, :job_title, :salary);
if ( sqlca.sqlcode != 0 ) {
fprintf(stderr, "Insert Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
/* SELECT DML */
emp_number = 10;
EXEC SQL SELECT ename, job, sal INTO :emp_name, :job_title, :salary
FROM emp
WHERE empno = :emp_number;
if ( sqlca.sqlcode != 0 ) {
fprintf(stderr, "Select Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
printf(" SELECT result : ename=[%s], job=[%s], sal=[%d]\n",
emp_name, job_title, salary);
/* UPDATE DML */
emp_number = 10;
salary = 2000;
EXEC SQL UPDATE emp SET sal = :salary WHERE empno = :emp_number;
if ( sqlca.sqlcode != 0 ) {
fprintf(stderr, "Update Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
/* Cursor Create */
EXEC SQL DECLARE cur_emp CURSOR FOR
SELECT ename, job, sal FROM emp;
/* Cursor Open */
EXEC SQL OPEN cur_emp;
if(sqlca.sqlcode != 0 ) {
fprintf(stderr, "OPEN CSR ERROR %d\n",sqlca.sqlcode);
exit(-1);
}
/* Fetch Cursor */
for(;;)
{
EXEC SQL FETCH cur_emp INTO :emp_name, :job_title, :salary;
switch(sqlca.sqlcode)
{
case 0:
printf("Fetch Result : emp_name[%s], job[%s], sal=[%d]\n",
emp_name, job_title, salary );
continue;
case 1403: /* Not Found Data */
break;
default :
fprintf(stderr, "FETCH CSR ERROR %d",sqlca.sqlcode);
exit(-1);
}
break;
}
/* Cursor Close */
EXEC SQL CLOSE cur_emp;
/* Dynamic SQL */
strcpy(dynamic_stmt, "DELETE FROM EMP WHERE EMPNO = :v1");
EXEC SQL PREPARE sql_stmt FROM :dynamic_stmt;
dynamic_emp_number = 10;
EXEC SQL EXECUTE sql_stmt USING :dynamic_emp_number;
/* Disconnect */
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}
Altibase#
#include <stdio.h>
#include <stdlib.h>
EXEC SQL BEGIN DECLARE SECTION;
char emp_name[21];
char job_title[21];
int salary;
int emp_number;
char uid[10];
char pwd[10];
char dynamic_stmt[120];
int dynamic_emp_number;
EXEC SQL END DECLARE SECTION;
int main(void)
{
strcpy(uid, "SYS" );
strcpy(pwd, "MANAGER");
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;
if ( sqlca.sqlcode != SQL_SUCCESS ) {
fprintf(stderr, "DataBase Connect Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
/* INSERT */
/* value setting */
emp_number = 10;
strcpy(emp_name, "altibase1");
strcpy(job_title, "dba1");
salary = 10000;
/* INSERT DML */
EXEC SQL INSERT INTO emp (empno, ename, job, sal)
VALUES (:emp_number, :emp_name, :job_title, :salary);
if ( sqlca.sqlcode != SQL_SUCCESS ) {
fprintf(stderr, "DataBase Connect Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
emp_number = 20;
strcpy(emp_name, "altibase2");
strcpy(job_title, "dba2");
salary = 20000;
EXEC SQL INSERT INTO emp (empno, ename, job, sal)
VALUES (:emp_number, :emp_name, :job_title, :salary);
/* SELECT DML */
emp_number = 10;
EXEC SQL SELECT ename, job, sal INTO :emp_name, :job_title, :salary
FROM emp
WHERE empno = :emp_number;
if ( sqlca.sqlcode != SQL_SUCCESS ) {
fprintf(stderr, "Select Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
printf(" SELECT result : ename=[%s], job=[%s], sal=[%d]\n",
emp_name, job_title, salary);
/* UPDATE DML */
emp_number = 10;
salary = 2000;
EXEC SQL UPDATE emp SET sal = :salary WHERE empno = :emp_number;
if ( sqlca.sqlcode != SQL_SUCCESS ) {
fprintf(stderr, "Update Error : [%d]!!!", sqlca.sqlcode);
exit(-1);
}
/* Cursor Create */
EXEC SQL DECLARE cur_emp CURSOR FOR
SELECT ename, job, sal FROM emp;
/* Cursor Open */
EXEC SQL OPEN cur_emp;
if(sqlca.sqlcode != SQL_SUCCESS ) {
fprintf(stderr, "OPEN CSR ERROR %d\n",sqlca.sqlcode);
exit(-1);
}
/* Fetch Cursor */
for(;;)
{
EXEC SQL FETCH cur_emp INTO :emp_name, :job_title, :salary;
switch(sqlca.sqlcode)
{
case SQL_SUCCESS:
printf("Fetch Result : emp_name[%s], job[%s], sal=[%d]\n",
emp_name, job_title, salary );
continue;
case SQL_NO_DATA: /* Not Found Data */
break;
default :
fprintf(stderr, "FETCH CSR ERROR %d %s\n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
exit(-1);
}
break;
}
/* Cursor Close */
EXEC SQL CLOSE cur_emp;
/* Dynamic SQL */
strcpy(dynamic_stmt, "DELETE FROM EMP WHERE EMPNO = ?");
EXEC SQL PREPARE sql_stmt FROM :dynamic_stmt;
dynamic_emp_number = 10;
EXEC SQL EXECUTE sql_stmt USING :dynamic_emp_number;
/* Disconnect */
EXEC SQL DISCONNECT;
exit(0);
}