37 - APIs#
Approaches to Database Programming#
Embedding database commands in a a general-purpose programing language
Embedded SQL
Using a library of database functions
Library of functions available to host programming language
Application programming interface (API)
Designing a brand-new language
Database programming language designed from scratch
Impedance Mismatch#
Differences between database model and programming language model
Binding for each host programming language
Specifies for each attribute type the compatible programming language types
Cursor or iterator variable
Loop over the tuples in a query result
Embedded SQL, Dynamic SQL, and SQLJ#
Embedded SQL
C language
SQLJ
Java language
Programming language called host language
SQL called data sublanguage

Embedded SQL#
Retrieving Single Tuples#
EXEC SQL
Prefix
Preprocessor separates embedded SQL statements from host language code
Terminated by matching
END-EXEC
Or by a semicolon
Shared Variables
Used in both the C program and the embedded SQL statements
Prefixed by a colon in SQL statement
To connect to the database:
CONNECT TO <server name> AS <connection name>
AUTHORIZATION <user account name and password>;
To change a connection:
SET CONNECTION <connection name>;
To terminate a connection:
DISCONNECT <connection name>;
The SQLCODE
and SQLSTATE
communication variables are used by the DBMS to communicate exception or error conditions.
The SQLCODE
variable is
0 when the statement is executed successfully
100 when no more data is available in the query result
<0 when some error has occured
The SQLSTATE
variable is a string of 5 characters where ‘00000’ indicates there is no error or exception. Other values indicate certain errors or exceptions (e.g. ‘02000’ indicates ‘no more data’)
Example#
loop = 1;
while (loop) {
prompt("Enter a Social Security Number: ", ssn);
EXEC SQL
SELECT Fname, Minit, Lname, Address, Salary
INTO :fname, :minit, :lname, :address, :salary
FROM EMPLOYEE WHERE Ssn = :ssn;
if (SQLCODE == 0) printf(fname, minit, lname, address, salary)
else printf("Social Security Number does not exist: " ssn);
prompt("More Social Security Numbers (enter 1 for Yes, 0 for No): ", loop);
}
Retrieving Multiple Tuples Using Cursors#
A cursor is a pointer to a single row (tuple) of the result of a query.
The OPEN CURSOR
command fetches the query result and sets the cursor to a position before the first row in the result. This then becomes the current row of the cursor.
FETCH
commands move the cursor to the next row in the result of a query.
FOR UPDATE OF
lists the names of any attributes that will be updated by the program.
Fetch orientation is added using the values: NEXT
, PRIOR
, FIRST
, LAST
, ABSOLUTE i
, and RELATIVE i
.
DECLARE <cursor name> [INSENSITIVE] [SCROLL] CURSOR
[WITH HOLD] FOR <query specification>
[ORDER BY <ordering specification>]
[FOR READ ONLY | FOR UPDATE [OF <attribute list>]];
WITH HOLD
indicates that the cursor will not be closed
Example#
prompt("Enter the Department Name: ", dname);
EXEC SQL
SELECT Dnumber INTO :dnumber
FROM DEPARTMENT WHERE Dname = :dname;
EXEC SQL DECLARE EMP CURSOR FOR
SELECT Ssn, Fname, Minit, Lname, Salary
FROM EMPLOYEE WHERE Dno = :dnumber
FOR UPDATE OF Salary;
EXEC SQL OPEN EMP;
EXEC SQL FETCH FROM EMP INTO :ssn, :fname, :minit, :lname, :salary;
while (SQLCODE == 0) {
printf("Employee name is:" Fname, Minit, Lname);
prompt("Enter the raise amount: ", raise);
EXEC SQL
UPDATE EMPLOYEE
SET Salary = Salary + :raise
WHERE CURRENT OF EMP
EXEC SQL FETCH FROM EMP INTO :ssn, :fname, :minit, :lname, :salary;
}
EXEC SQL CLOSE EMP;
Dynamic SQL#
Dynamic SQL executes different SQL queries or updates dynamically at runtime.
This includes dynamic updates and dynamic queries.
EXEC SQL BEGIN DECLARE SECTION;
varchar sqlupdatestring[256];
EXEC SQL END DECLARE SECTION;
prompt("Enter the Update Command: ", sqlupdatestring);
EXEC SQL PREPARE sqlcommand FROM :sqlupdatestring;
EXEC SQL EXECUTE sqlcommand;
SQLJ#
SQLJ is a standard adopted by several vendors for embedding SQL in Java.
It involves importing several class libraries, default context, and uses exceptions for error handling (SQLException
is used to return errors or exception conditions).
This is how to import the libraries needed for SQLJ for Java programs in Oracle and establish a connection and default context:
import java.sql.*;
import java.io.*;
import sqlj.runtime.*;
import sqlj.runtime.ref.*;
import oracle.sqlj.runtime.*;
DefaultContext cntxt = oracle.getConnection("<url name>", "<user name>", "<password>", true);
DefaultContext.setDefaultContext(cntxt);
Our coding examples will use the following variables:
String dname, ssn, fname, fn, lname, ln, bdate, address;
char sex, minit, mi;
double salary, sal;
int dno, dnumber;
Retrieving a Single Tuple with SQLJ#
ssn = readEntry("Enter a Social Security Number: ");
try {
#sql {SELECT Fname, Minit, Lname, Address, Salary
INTO :fname, :minit, :lname, :address, :salary
FROM EMPLOYEE WHERE Ssn = :ssn}
} catch (SQLException se) {
System.out.println("Social Security Number does not exist: " + ssn);
return;
}
System.out.println(fname + " " + minit + " " + lname + " " + address + " " + salary);
Retrieving Multiple Tuples with SQLJ#
An iterator is an object associated with a collection (set or multiset) of records in a query result.
A named iterator is associated with a query result by listing attribute names and types in the query result.
A positional iterator lists only attribute types in the query result.
This example uses a named iterator to print employee information from a given department:
dname = readEntry("Enter the Department Name: ");
try {
#sql {SELECT Dnumber INTO :dnumber
FROM DEPARTMENT WHERE Dname = :dname};
} catch (SQLException se) {
System.out.println("Department does not exist: " + dname);
return;
}
System.out.println("Employee information for Department: " + dname);
#sql iterator Emp(String ssn, String fname, String minit, String lname, double salary);
Emp e = null;
#sql e = {SELECT ssn, fname, minit, lname, salary
FROM EMPLOYEE WHERE Dno = :dnumber};
while (e.next()) {
System.out.println(e.ssn + " " + e.fname + " " e.minit + " " + e.lname + " " + e.salary)
}
e.close();
This example uses a positional iterator to print employee information from a given department:
dname = readEntry("Enter the Department Name: ");
try {
#sql {SELECT Dnumber INTO :dnumber
FROM DEPARTMENT WHERE Dname = :dname};
} catch (SQLException se) {
System.out.println("Department does not exist: " + dname);
return;
}
System.out.println("Employee information for Department: " + dname);
#sql iterator Emppos(String, String, String, String, double);
Emppos e = null;
#sql e = {SELECT ssn, fname, minit, lname, salary
FROM EMPLOYEE WHERE Dno = :dnumber};
#sql {FETCH :e INTO :ssn, :fn, :mi, :ln, :sal}
while (!e.endFetch()) {
System.out.println(ssn + " " + fn + " " mi + " " + ln + " " + sal)
}
e.close();