Databases 2010
Embedded SQL
Christian S. JensenComputer Science, Aarhus University
Acknowledgments: revised version of slides developed by Michael I. Schwartzbach
2Embedded SQL
Embedded SQL
SQL is rarely written as ad-hoc queriesusing the generic SQL interfaceThe typical scenario:
SQL is embedded in the server application code
client server database
3Embedded SQL
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
4Embedded SQL
JDBC – Java Database Connectivity
A common Java framework for SQL databases• java.sql.*
Each vendor provides a driver class• com.ibm.db2.jcc.DB2driver• oracle.jdc.driver.OracleDriver• com.microsoft.sqlserver.jdbc.SQLServerDriver• org.gjt.mm.mysql.Driver
SQL statements are built as string expressionsResults are accessed through a cursor
5Embedded SQL
Running a JDBC Application
Initialization
Processing
Termination
load drivercreate connection
generate SQLprocess results
end connectionrelease data structures
java.sql.DriverManagerjava.sql.Connection
java.sql.Statementjava.sql.ResultSet
java.sql.Connectionjava.sql.Statement
6Embedded SQL
A Simple Example
import java.sql.*;
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);Statement stmt = con.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM Rooms");while (rs.next())
System.out.println(rs.getString(1)+" "+rs.getString(2));stmt.close();con.close();
} catch(Exception e) { e.printStackTrace(); }}
}
Dreyer-201 12Zuse-127 10Shannon-164 30Shannon-157 40Shannon-159 38Wiener-026 30Hopper-334A 4Ada-333 26Turing-029 8Turing-129 8Turing-230 12Turing-130 12Turing-030 12Stibitz-123 12Hopper-334 4Shannon-156 24Stibitz-113 12Undervisning 36Store-Aud 152Lille-Aud 70Turing-014 26Turing-229 8D-01 25D-02 18D-03 18Aud-D1 100Aud-D2 100Aud-D4 62Aud-G1 85Aud-G2 85Kol-G3 22Kol-G4 22G-32 20G-33 20Aud-E 286Aud-F 165...
7Embedded SQL
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
8Embedded SQL
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();
9Embedded SQL
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);
10Embedded SQL
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
11Embedded SQL
Using Result Sets
A ResultSet object manages a cursor on rows
ResultSet rs = stmt.executeQuery("...");while (rs.next()) {...
}rs.close();
room capacityTuring-216 4Ada-333 26Aud-E 286
rs
12Embedded SQL
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
13Embedded SQL
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 4Ada-333 26Aud-E 286
rs
14Embedded SQL
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);
15Embedded SQL
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 capacityTuring-216 4Ada-333 26Aud-E 286ADA-333 26rs
16Embedded SQL
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 capacityTuring-216 4Ada-333 26Aud-E 286Turing-310 4
rs
17Embedded SQL
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();
18Embedded SQL
Arguments to Prepared Statements
Use ? symbols for variablesInsert 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();
19Embedded SQL
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
20Embedded SQL
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 VARCHARColumn 2 has name CAPACITY, SQL type 4 and JDBC type INTEGER
21Embedded SQL
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
22Embedded SQL
SQL Injection Cartoon
23Embedded SQL
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 cursorsStatic binding as a DB2 package• better performance• stronger security authorization
24Embedded SQL
Processing SQLJ Programs
Foo.sqlj
Foo.java
translator Foo.ser
javac
binder
Foo.class
25Embedded SQL
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(); }}
}