2 Motivation

! Pros and cons of SQL " Very high-level, possible to optimize SQL: Programming " Not intended for general-purpose computation ! Solutions " Augment SQL with constructs general-purpose CPS 196.3 programming languages (SQL/PSM) Introduction to Database Systems " Use SQL together with general-purpose programming languages (JDBC, embedded SQL, etc.)

3 4 JDBC Connections

! JDBC (Java DataBase Connectivity) is an API that allows a … Java program to access databases // Connection URL is a DBMS-specific string: String url = … ”jdbc:db2://rack40.cs.duke.edu/cps116”; // Use the JDBC package: import java..*; // Making a connection: … Connection con = public class … { DriverManager.getConnection(url); … … static { // Closing a connection: // Load the JDBC driver: Class.forName(”COM.ibm.db2.jdbc.net.DB2Driver”); con.close(); … … } … }

5 6 Statements Query results

… … // Create an object for sending SQL statements: // Execute a query and get its results: Statement stmt = con.createStatement(); ResultSet rs = // Execute a query and get its results: stmt.executeQuery(”SELECT SID, name FROM Student”); ResultSet rs = // Loop through all result rows: stmt.executeQuery(”SELECT SID, name FROM Student”); while (rs.next()) { // Work on the results: // Get column values: … int sid = rs.getInt(1); // Execute a modification (returns the number of rows affected): String name = rs.getString(2); int rowsUpdated = // Work on sid and name: stmt.executeUpdate … (”UPDATE Student SET name = ’Barney’ WHERE SID = 142”); } // Close the statement: // Close the ResultSet: stmt.close(); rs.close(); … …

1 7 8 Other ResultSet features Prepared statements: motivation

… ! Move the (pointing to the current row) Statement stmt = con.createStatement(); backwards and forwards, or position it anywhere for (int age=0; age<100; age+=10) { ResultSet rs = stmt.executeQuery within the ResultSet (”SELECT AVG(GPA) FROM Student” + ” WHERE age >= ” + age + ” AND age < ” + (age+10)); ! Update/delete the database row corresponding to // Work on the results: … the current result row } … " Analogous to the update problem ! Every time an SQL string is sent to the DBMS, the DBMS ! Insert a row into the database must perform parsing, semantic analysis, optimization, " Analogous to the view update problem compilation, and then finally execution ! These costs are incurred 10 times in the above example, even though all strings are essentially the same query (with different parameter values)

9 10 Prepared statements: syntax Transaction processing

… ! Set isolation level for the current transaction // Prepare the statement, using ? as placeholders for actual parameters: PreparedStatement stmt = con.prepareStatement " con.setTransactionIsolationLevel(l); (”SELECT AVG(GPA) FROM Student WHERE age >= ? AND age < ?”); for (int age=0; age<100; age+=10) { " Where l is one of TRANSACTION_SERIALIZABLE (default), // Set actual parameter values: TRANSACTION_REPEATABLE_READ, TRANSACTION_READ_COMITTED, and stmt.setInt(1, age); TRANSACTION_READ_UNCOMMITTED stmt.setInt(2, age+10); ResultSet rs = stmt.executeQuery(); ! Set the transaction to be read-only or read/write (default) // Work on the results: … " con.setReadOnly(true|false); } ! … Turn on/off AUTOCOMMIT (commits every single statement) " con.setAutoCommit(true|false); ! The DBMS performs parsing, semantic analysis, optimization, and compilation only once, when it prepares ! Commit/rollback the current transaction (when the statement AUTOCOMMIT is off) " ! At execution time, the DBMS only needs to check con.commit(); parameter types and validate the compiled execution plan " con.rollback();

11 12 Odds and ends of JDBC JDBC drivers – Types I, II

! Most methods can throw SQLException ! Type I (bridge): translate JDBC calls to a standard " Make sure your code catches them API not native to the DBMS (e.g., JDBC-ODBC " getSQLState() returns the standard SQL error code bridge) " getMessage() returns the error message " Driver is easy to build using existing standard API’s ! Methods for examining metadata in databases " Extra layer of API adds overhead ! Methods to retrieve the value of a column for all result rows into an array without calling ResultSet.next() in a loop ! Type II (native API, partly Java): translates JDBC ! Methods to construct and execute a batch of SQL calls to DBMS-specific client API calls statements together " DBMS-specific client library needs to be installed on each client ! … " Good performance

2 13 14 JDBC drivers – Types III, IV Other database programming methods

! Type III (network bridge): sends JDBC requests to a ! API approach middleware server which in turn communicates with a " SQL commands are sent to the DBMS at runtime database " Examples: JDBC, ODBC (for C/C++/VB), Perl DBI " Client JDBC driver is completely Java, easy to build, and does not need to be DBMS-specific " These API’s are all based on the SQL/CLI (Call-Level " Middleware adds translation overhead Interface) standard ! Type IV (native protocol, full Java): converts JDBC ! Embedded SQL approach requests directly to native network protocol of the DBMS " SQL commands are embedded in application code " Client JDBC driver is completely Java but is also DBMS-specific " A precompiler checks these commands at compile-time " Good performance and convert them into DBMS-specific API calls " Examples: embedded SQL for C/C++, SQLJ (for Java)

15 16 Embedded C example Embedded C example continued

… /* Open the cursor: */ /* Declare variables to be “shared” between the application EXEC SQL OPEN CPS196Student; /* Specify exit : */ and the DBMS: */ EXEC SQL WHENEVER NOT FOUND DO break; EXEC SQL BEGIN DECLARE SECTION; /* Loop through result rows: */ int thisSID; float thisGPA; while (1) { EXEC SQL END DECLARE SECTION; /* Get column values for the current row: */ EXEC SQL FETCH CPS196Student INTO :thisSID, :thisGPA; /* Declare a cursor: */ printf(”SID %d: current GPA is %f\n”, thisSID, thisGPA); EXEC SQL DECLARE CPS196Student CURSOR FOR /* Update GPA: */ printf(”Enter new GPA: ”); SELECT SID, GPA FROM Student scanf(”%f”, &thisGPA); WHERE SID IN EXEC SQL UPDATE Student SET GPA = :thisGPA (SELECT SID FROM Enroll WHERE CID = ’CPS196’) WHERE CURRENT OF CPS196Student; FOR UPDATE; } /* Close the cursor: */ … EXEC SQL CLOSE CPS196Student;

17 18 Pros and cons of embedded SQL SQL/PSM stored procedures/functions

! Pros ! CREATE PROCEDURE proc_name ( parameter_declarations ) " More compile-time checking (syntax, type, schema, …) local_declarations procedure_body; " Code could be more efficient (if the embedded SQL statements do not need to checked and recompiled at ! CREATE FUNCTION func_name ( parameter_declarations ) run-time) RETURNS return_type local_declarations ! Cons procedure_body; " DBMS-specific ! CALL proc_name ( parameters ); • Vendors have different precompilers which translate code into ! Inside procedure body: different native API’s SET variable = CALL func_name ( parameters ); • Application executable is not portable (although code is) • Application cannot talk to different DBMS at the same time

3 19 20 SQL/PSM example SQL/PSM example continued

CREATE FUNCTION SetMaxGPA(IN newMaxGPA FLOAT) -- Fetch the first result row: RETURNS INT OPEN studentCursor; -- Enforce newMaxGPA; return number of rows modified. FETCH FROM studentCursor INTO thisGPA; BEGIN -- Loop over all result rows: DECLARE rowsUpdated INT DEFAULT 0; WHILE noMoreRows <> 1 DO DECLARE thisGPA FLOAT; IF GPA > newMaxGPA THEN -- A cursor to range over all students: -- Enforce newMaxGPA: DECLARE studentCursor CUSOR FOR SELECT GPA FROM Student UPDATE Student SET Student.GPA = newMaxGPA FOR UPDATE; WHERE CURRENT OF studentCursor; -- Set a flag whenever there is a “not found” exception: -- Update count: DECLARE noMoreRows INT DEFAULT 0; SET rowsUpdated = rowsUpdated + 1; DECLARE CONTINUE HANDLER FOR NOT FOUND END IF; SET noMoreRows = 1; -- Fetch the next result row: … (see next slide) … FETCH FROM studentCursor INTO thisGPA; RETURN rowsUpdated; END WHILE; END CLOSE studentCursor;

21 Other SQL/PSM features

! Assignment using scalar query results " SELECT INTO ! Other loop constructs " FOR, REPEAT UNTIL, LOOP ! Flow control " GOTO ! Exceptions " SIGNAL, RESIGNAL

4