Académique Documents
Professionnel Documents
Culture Documents
You can embed SQL statements into many programming languages procedural power (loops, variables, etc.) The main components of embedded SQL programming:
Regular program blocks SQL code Methods to connect to the database, invoke the SQL code and retrieve results Methods to pass data from program variables to the SQL code Methods to retrieve data from the result of queries to program variables
9/16/2012
Example
#include <stdio.h> exec sql include sqlca; char user_prompt[] = "Please enter username and password: char cid_prompt[] = "Please enter customer ID: "; ";
int main() { exec sql begin declare section; char cust_id[5]; char cust_name[14]; float cust_discnt; char user_name[20], user_pwd[20]; exec sql end declare section;
*/
*/
exec sql whenever sqlerror goto report_error; /* error trap condition exec sql whenever not found goto notfound; /* not found condition 9/16/2012 4380 Database Systems - Fall 2002
*/ */ 2
Example
exec sql connect :user_name identified by :user_pwd; /* ORACLE format: connect */
while (prompt(cid_prompt, 1, cust_id, 4) >= 0) { exec sql select cname, discnt into :cust_name, :cust_discnt /* retrieve cname, discnt */ from customers where cid = :cust_id; exec sql commit work; /* release read lock on row */ printf("CUSTOMER'S NAME IS %s AND DISCNT IS %5.1f\n", cust_name, cust_discnt); /* NOTE, (:) not used here continue; }
*/
9/16/2012
ProC
Each ESQL statement starts with EXEC SQL keyword and ends with a semicolon ; A pre-compiler will scan a program file and only read the statements enclosed within EXEC SQL statements and disregard everything else. SQLCA is a specific data structure for storing status codes of all SQL operations /* always have this for error handling*/ exec sql include sqlca ;
9/16/2012 4380 Database Systems - Fall 2002 4
Program.pc
Program.c
9/16/2012
Variables in ESQL
All variables that will be used in an SQL statement must be declared using an ESQL declaration and data type exec sql begin declare section ; VARCHAR e_name[30], username[30], passwd[30] ; INTEGER e_ssn, e_dept_id ; exec sql end declare section ; You can use almost any SQL command in ESQL as long as proper input to these commands are provided in the form of program variables. To execute any command, you must first connect to a database in which all your tables reside. exec sql connect :username identified by :passwd ;
9/16/2012
In C, the end of a string is identified by the null character \0. Hence, Sibel would be stored as characters S,i,b,e,l,\0. In Oracle, the length of a string is stored together with the string and there is no special end of string character. If you convert a data string from Oracle to C, you must pad it with \0 manually!
The data type VARCHAR e_name[30] is translated by the precompiler to the following structure:
struct { unsigned short len unsigned char arr[30] } e_name ;
9/16/2012 4380 Database Systems - Fall 2002 8
More on strings
Putting the pieces together: strcpy(username.arr, Sibel Adali) ; username.len = strlen(Sibel Adali) ; strcpy(passwd.arr, tweety-bird) ; passwd.len = strlen(tweety-bird) ; exec sql connect :username identified by :passwd ; scanf(%d, &e_ssn) ; exec sql select name, dept_id into :e_name, :e_dept_id from employee where ssn = :e_ssn ; e_name.arr[e_name.len] = \0 ; /* so can use string in C*/ printf(%s, e_name.arr) ; exec sql commit work ; /* make any changes permanent */ exec sql disconnect ; /* disconnect from the database */
9/16/2012 4380 Database Systems - Fall 2002 9
ESQL - Cursors
When a select statement returns a set of tuples, then the tuples (rows) can only be retrieved one by one. programming language variables can contain only one value at a time this is sometimes called an impedance mismatch Cursor operations declare a cursor using a regular SQL query (no into). exec sql declare emps_dept cursor for select ssn, name from employee where dept_id = :e_dept_id ;
9/16/2012
10
read the current row pointed to by the cursor using fetch. At the end of fetch, the cursor is moved to point to the next tuple. exec sql fetch emps_dept into :e_ssn, :e_name ;
9/16/2012
11
9/16/2012
13
For these updates to have an effect, the cursor must not be INSENSITIVE.
9/16/2012 4380 Database Systems - Fall 2002 14
Constraints
When constraints are violated, they cause an exception (or sqlerror) to be thrown. When are constraints violated?
If constraint checking for a constraint is immediate, as soon as an SQL statement causes the constraint to become false, it is rolled back. If a constraint is defined to be deferrable, then the constraint is not checked until a transaction tries to commit. Then, if it is violated, the whole transaction is rolled back.
CONSTRAINT name CHECK DEFERRABLE
4380 Database Systems - Fall 2002 15
9/16/2012
Transactions
The most common ESQL statements are SELECT, INSERT INTO, and UPDATE statements. A transaction in a program starts with the first read or write to a database (not with connect) and ends when either one of the following commands is executed exec sql commit work ; /* changes to the database are made permanent */ exec sql rollback work ; /* restore all tuples to their original values */ If a program did not complete correctly, then changes can be undone to restore a consistent state.
9/16/2012
16
Dynamic SQL
In Dynamic SQL, embedded SQL statements are created on the fly using strings! these strings are fed to an exec sql statement exec sql execute immediate :sql_string Since dynamic SQL statements are not known to the pre-compiler at compile time, they must be optimized at run time! Create a query once using a prepare statement and run it multiple times using the execute statement. strcopy(sqltext.arr, delete from employee where ssn = ?) ; sqltext.len=str.len(sqltext.arr) ; exec sql prepare del_emp from :sqltext ; exec sql execute del_emp using :cust_id ;
9/16/2012 4380 Database Systems - Fall 2002 17
SQLDA
When we execute a dynamic SQL statement, we do not know which columns will be returned and how many columns will be returned. The SQLDA descriptor definition allows us to find the number of columns and the value for each column. exec sql include sqlda ; exec sql declare sel_curs cursor for sel_emps ; exec sql prepare sel_emps from :sqltext ; exec sql describe sel_emps into sqlda ; exec sql open sel_curs ; exec sql fetch sel_curs using descriptor sqlda ;
9/16/2012 4380 Database Systems - Fall 2002 18
JDBC
Driver is a piece of software that enables communication between a program and a database system (DMBS specific packages). It implements a number of main classes:
Connection (opening, closing, committing) Statement (executing queries) Result set (going through cursors, extracting information)
9/16/2012
19
JDBC
import java.sql.*; import oracle.sql.*; import oracle.jdbc.driver.*; class Employee { public static void main (String args []) throws SQLException {//Set your user name and the password String userName = "dummy" ; String passWord = "dummy" ; // Load the Oracle JDBC driver DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@acadoracle.server.rpi.edu:1521:ora9", userName,passWord);
9/16/2012 4380 Database Systems - Fall 2002 20
JDBC
// Create a statement which will return a cursor that // will allow you to scroll the result set using both // "next" and "previous" methods try { Statement stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
9/16/2012
21
JDBC
// Iterate through the result and print the item names while (rset.next ()) { //Get item name, which is the first column System.out.println (rset.getString (1)); PreparedStatement pstmt = conn.prepareStatement ("SELECT name FROM owners WHERE oid = ?") ; //Feed the owner id retrieved from rset into pstmt pstmt.setInt(1, rset.getInt (2)); ResultSet dset = pstmt.executeQuery() ; if (dset.next()) System.out.println(dset.getString (1)); } } } catch (SQLException) { error-handling-code } } }
9/16/2012 4380 Database Systems - Fall 2002 22