Databases 2010 Embedded SQL

Christian S. Jensen Computer Science, Aarhus University

Acknowledgments: revised version of slides developed by Michael I. Schwartzbach Embedded SQL

ƒ SQL is rarely written as ad-hoc queries using the generic SQL interface ƒ The typical scenario:

client server database

ƒ SQL is embedded in the server application code

Embedded SQL 2 Static vs. Dynamic SQL

ƒ Static SQL • syntactic extension of host language • predefined and stored in the database • typical use: monthly accounting statements • checked in advance, efficient • SQLJ for Java, supported by, e.g., DB2 ƒ Dynamic SQL • API in host language • dynamically interpreted by the database • typical use: web applications • highly flexible • JDBC for Java, works well with Hibernate

Embedded SQL 3 JDBC – Java Database Connectivity

ƒ A common Java framework for SQL databases • java..* ƒ Each vendor provides a driver class • com..db2.jcc.DB2driver • oracle.jdc.driver.OracleDriver • com.microsoft.sqlserver.jdbc.SQLServerDriver • org.gjt.mm.mysql.Driver

ƒ SQL statements are built as string expressions ƒ Results are accessed through a cursor

Embedded SQL 4 Running a JDBC Application

load driver java.sql.DriverManager Initialization create connection java.sql.Connection

generate SQL java.sql.Statement Processing process results java.sql.ResultSet

end connection java.sql.Connection Termination release data structures java.sql.Statement

Embedded SQL 5 A Simple Example

Dreyer-201 12 import java.sql.*; Zuse-127 10 Shannon-164 30 Shannon-157 40 public class Test { Shannon-159 38 public static void main(String args[]) { Wiener-026 30 Hopper-334A 4 Connection con; Ada-333 26 Turing-029 8 try { Turing-129 8 String server = "localhost"; Turing-230 12 Turing-130 12 String port = "50000"; Turing-030 12 String url = "jdbc:db2://"+server+":"+port+"/sample"; Stibitz-123 12 Hopper-334 4 String userid = ”userid"; Shannon-156 24 Stibitz-113 12 String password = ”password"; Undervisning 36 Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance(); Store-Aud 152 Lille-Aud 70 con = DriverManager.getConnection(url, userid, password); Turing-014 26 Statement stmt = con.createStatement(); Turing-229 8 D-01 25 ResultSet rs = stmt.executeQuery("SELECT * FROM Rooms"); D-02 18 D-03 18 while (rs.next()) Aud-D1 100 System.out.println(rs.getString(1)+" "+rs.getString(2)); Aud-D2 100 Aud-D4 62 stmt.close(); Aud-G1 85 con.close(); Aud-G2 85 Kol-G3 22 } catch(Exception e) { e.printStackTrace(); } Kol-G4 22 G-32 20 } G-33 20 } Aud-E 286 Aud-F 165 ...

Embedded SQL 6 Creating A Connection

ƒ Load the appropriate driver class: Class.forName("com.ibm.db2.jcc.DB2Driver");

ƒ Create a connection object: DriverManager.getConnection(url, userid, password);

ƒ URL structure (for DB2) • jdbc:db2://server:port/database • the name of your own machine is localhost • the standard port number is 50000 • the name of the database is, e.g., SAMPLE

Embedded SQL 7 Simple SQL Statements

ƒ Create a statement object: Statement stmt = con.createStatement();

ƒ The statement object is used many times • stmt.executeQuery("…"); • stmt.executeUpdate("…");

ƒ And is finally closed • stmt.close();

Embedded SQL 8 Transactions

ƒ Default auto-commits after every statement, change with • con.setAutoCommit(false); • con.commit(); • con.rollback();

ƒ Transaction isolation levels • con.setTransactionIsolation(level); • Connection.TRANSACTION_READ_COMMITTED • Connection.TRANSACTION_READ_UNCOMMITTED • Connection.TRANSACTION_READ_REPEATABLE_READ • Connection.TRANSACTION_SERIALIZABLE • con.setReadOnly(true); Embedded SQL 9 Impedance Mismatch

ƒ Java uses native types • int, char[], String, ... • collection classes ƒ SQL uses tables • CHAR(7), VARCHAR(20), FLOAT, DATE, ... • possibly huge amounts of data ƒ Not obvious how to translate tables into Java objects

ƒ Results are instead accessed using cursors

Embedded SQL 10 Using Result Sets

ƒ A ResultSet object manages a cursor on rows

ƒ ResultSet rs = stmt.executeQuery("..."); while (rs.next()) { ... } rs.close();

room capacity Turing-216 4 rs Ada-333 26 Aud-E 286

Embedded SQL 11 Navigating With Cursors

ƒ A cursor can by default only move forward • rs.next();

ƒ A Boolean result tells if the move was possible • looks like an iterator object

ƒ An ORDER BY clause determines the order

Embedded SQL 12 Reading With Cursors

ƒ Column index or column name • String room = rs.getString(1); • int capacity = rs.getInt("capacity"); ƒ Different result types • getString(...) • getInt(...) • java.sql.Time time = getTime(...) ƒ Check for NULL • wasNull() room capacity Turing-216 4 rs Ada-333 26 Aud-E 286

Embedded SQL 13 Better Cursors

ƒ A result set can be made scrollable and updatable • stmt = createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); • rs.previous(); • rs.first(); • rs.last(); • rs.absolute(42);

Embedded SQL 14 Modifications with Cursors

ƒ A result set can then be updated • rs.updateString("room","ADA-333"); ƒ Updates can be pushed to the database • rs.updateRow(); ƒ Rows can be deleted both places • rs.deleteRow();

room capacity Turing-216 4 rs ADA-333Ada-333 2626 Aud-E 286

Embedded SQL 15 Insertions With Cursors

ƒ A special virtual insert row exists

ƒ rs.moveToInsertRow(); rs.updateString("room”,"Turing-310"); rs.updateInt("capacity",4); rs.insertRow(); rs.moveToCurrentRow();

room capacity Turing-216 4 rs Ada-333 26 Aud-E 286 Turing-310 4

Embedded SQL 16 Prepared Statements

ƒ SQL statements may be prepared • checked and compiled once • executed multiple times

ƒ PreparedStatement pstmt = con.prepareStatement( "SELECT * FROM Rooms" ); ResultSet rs = pstmt.executeQuery();

Embedded SQL 17 Arguments to Prepared Statements

ƒ Use ? symbols for variables ƒ Insert values using absolute position

ƒ PreparedStatement pstmt = con.prepareStatement( "INSERT INTO Meetings VALUES(?,?,?,'dDB',?)" ); pstmt.setInt(1,34716); pstmt.setDate(2,new java.sql.Date(2010,8,23)); pstmt.setInt(3,14); pstmt.setString(4,"csj"); pstmt.executeUpdate();

Embedded SQL 18 Metadata

ƒ java.sql.ResultSetMetaData • reflectively describes the structure of a result • names and types of columns • allows generic queries

ƒ java.sql.DatabaseMetaData • reflectively describes the structure of a database • name, version, tables, supported SQL types • allows generic connections

Embedded SQL 19 Result Set Metadata

ƒ rs = stmt.executeQuery("SELECT * FROM Rooms"); ResultSetMetaData rsm = rs.getMetaData(); int columns = rsm.getColumnCount(); for (int i=1; i<=columns; i++) { System.out.println( "Column "+i+" "+ "has name "+rsm.getColumnName(i)+", " "SQL type "+rsm.getColumnType(i)+" and " "JDBC type "+rsm.getColumnTypeName(i) ); }

Column 1 has name ROOM, SQL type 12 and JDBC type VARCHAR Column 2 has name CAPACITY, SQL type 4 and JDBC type INTEGER

Embedded SQL 20 SQL Injection Attacks

ƒ Be careful with dynamic SQL:

"SELECT * FROM Users WHERE userid ='" + userid + "'"

ƒ Fine if userid is "mis" ƒ Bad if userid is "x' OR 'y'='y" • all data is revealed ƒ Worse if userid is ”x';DROP TABLE Users;--" • all data is deleted

ƒ Prepared statements avoid this problem Embedded SQL 21 SQL Injection Cartoon

Embedded SQL 22 SQLJ

ƒ An extension of Java for SQL programming • SQL syntax mixed with Java syntax • a preprocessor generates Java and SQL code

ƒ Simpler syntax • syntax and type checking at compile time ƒ Strongly typed cursors ƒ Static binding as a DB2 package • better performance • stronger security authorization

Embedded SQL 23 Processing SQLJ Programs

Foo.sqlj

translator Foo.ser binder

Foo.java

javac

Foo.class

Embedded SQL 24 A Simple Example

import java.sql.*; import sqlj.runtime.*; import sqlj.runtime.ref.*;

public class Test { public static void main(String args[]) { Connection con; try { String server = "localhost"; String port = "50000"; String url = "jdbc:db2://"+server+":"+port+"/sample"; String userid = ”userid"; String password = ”password"; Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance(); con = DriverManager.getConnection(url, userid, password); DefaultContext.setDefaultContext(new DefaultContext(con)); #sql public iterator iter(String room, int capacity); #sql iter = { SELECT * FROM Rooms }; while (iter.next()) System.out.println(iter.room()+" "+iter.capacity()); con.close(); } catch(Exception e) { e.printStackTrace(); } } } Embedded SQL 25