Date post: | 13-Apr-2018 |
Category: |
Documents |
Upload: | maria-estrada |
View: | 216 times |
Download: | 0 times |
of 90
7/27/2019 8_DBApp
1/90
1
Database application development
(Real SQL programming)
February 27, 2014
7/27/2019 8_DBApp
2/90
2
Administrivia Announcements
- PS 4 is ready Reading assignment
- Chapter 6 Today
- Database application development (real SQL programming)
Acknowledgement- Some slide content courtesy of Ramakrishnan, Gehrke, and
Ullman
7/27/2019 8_DBApp
3/90
3
SQL in real programs
We have seen mainly how SQL is used at thegeneric query interface- in interactive mode, or- via a script file- (except with JDBC)
Reality is almost always different:- Conventional programs interacting with SQL
7/27/2019 8_DBApp
4/90
4
SQL in application code
SQL commands can be called from within a hostlanguage (e.g., C, C++, Java) program
- SQL statements can refer to host language variables(including special variables used to return status)
- Must include a statement to connect to the rightdatabase
7/27/2019 8_DBApp
5/90
5
Three options for integration
1. Embed SQL in a host language- Embedded SQL, Dynamic SQL- Ex: SQLJ
2. Create special API to call SQL commands- SQL/CLI- Ex: SQL/CLI for C, JDBC
3. Database stored procedures (code in a specializedlanguage is stored in the database itself)- SQL/PSM
7/27/2019 8_DBApp
6/90
6
Impedance mismatch
Differences between programming language model anddatabase model
Binding for each host programming language- Mapping between each SQL attribute type and its compatible
programming language type
SQL relations are (multi-)sets of records, with no a prioribound on the number of records- No such data structure exists in host programming languages
such as C++, Java
- SQL supports a mechanism called a cursor to handle this
7/27/2019 8_DBApp
7/90
7
Embedded SQL
7/27/2019 8_DBApp
8/90
8
Embedded SQL (static)
Key idea:- Embed SQL in the host language- SQL statements identified by a special prefix- A preprocessor(or precompiler) converts the SQL statements
into special API calls that fit with the surrounding host-languagecode
- Then a regular compiler is used to compile the code All embedded SQL statements begin with EXEC SQL, so
the preprocessor can find them
7/27/2019 8_DBApp
9/90
9
Language constructs
Connecting to a databaseEXEC SQL CONNECT
Declaring shared variables: To connect SQL and the host-language program, the two parts must share some variables
EXEC SQL BEGIN DECLARE SECTION
// variables here
EXEC SQL END DECLARE SECTION
StatementsEXEC SQL
7/27/2019 8_DBApp
10/90
10
Use of shared variables
In SQL, the shared variables must be preceded by acolon (:)- They may be used as constants provided by the host-language
program- They may get values from SQL statements and pass those
values to the host-language program
In the host language, shared variables behave like anyother variable
7/27/2019 8_DBApp
11/90
11
Example: shared variables
EXEC SQL BEGIN DECLARE SECTION
char c_sname[20];
long c_sid;
short c_rating;float c_age;
EXEC SQL END DECLARE SECTION
7/27/2019 8_DBApp
12/90
12
Communication variables
Two special errorvariables:- SQLCODE (long, is negative if an error has
occurred)
-SQLSTATE (char[6], predefined codes for commonerrors)
One of these two variables must be declared
7/27/2019 8_DBApp
13/90
13
Embedded SQL statement
EXEC SQL
INSERT INTO Sailors
VALUES (:c_sname, :c_sid, :c_rating, :c_age);
It is using shared variables
7/27/2019 8_DBApp
14/90
14
Example: Looking up prices
Using C with embedded SQL lets us sketch theimportant parts of a function that obtains a beer and abar, and looks up the price of that beer at that bar.
Assumes database has our usual Sells(bar, beer, price)relation
7/27/2019 8_DBApp
15/90
15
Example: C plus SQL
EXEC SQL BEGIN DECLARE SECTION;char theBar[21], theBeer[21];float thePrice;
EXEC SQL END DECLARE SECTION;
/* obtain values for theBar and theBeer */EXEC SQL SELECT price INTO :thePrice
FROM Sells
WHERE bar = :theBar AND beer = :theBeer;/* do something with thePrice */
20 chars +
endmarker
SELECT-INTO
7/27/2019 8_DBApp
16/90
16
Embedded queries
Embedded SQL has the same limitations asPSM (that we will see later) regarding queries:
- SELECT-INTO for a query guaranteed to produce asingletuple- For multipletuples, we have to use a cursor
7/27/2019 8_DBApp
17/90
17
Cursor statements
Declare a cursor cwith:EXEC SQL DECLARE cCURSOR FOR ;
Open and close cursor c with:EXEC SQL OPEN CURSOR c;
EXEC SQL CLOSE CURSOR c;
Fetch from c by:EXEC SQL FETCH c INTO ;
7/27/2019 8_DBApp
18/90
18
Example: Print Joes menu
Lets write C + SQL code to print Joes menu the list ofbeer-price pairs that we find in Sells(bar, beer, price)with bar = Joes Bar
A cursor will visit each Sells tuple that has bar = JoesBar
7/27/2019 8_DBApp
19/90
19
Example: Declarations
EXEC SQL BEGIN DECLARE SECTION;
char theBeer[21];
float thePrice;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE c CURSOR FOR
SELECT beer, price
FROM Sells
WHERE bar = Joes Bar;
The cursor declaration goes
outside the declare-section
7/27/2019 8_DBApp
20/90
20
Example: Executable part
EXEC SQL OPEN CURSOR c;
while(1) {
EXEC SQL FETCH c
INTO :theBeer, :thePrice;if (NO_MORE_TUPLES) break;
/* format and print theBeer and
thePrice */
}
EXEC SQL CLOSE CURSOR c;
The C style
of breaking
loops
// Using the following macro:
#define NO_MORE_TUPLES !(strcmp(SQLSTATE, 02000))
// 02000means no tuple was found
7/27/2019 8_DBApp
21/90
21
Cursors
A way to deal with impedance mismatch A cursor is essentially a tuple-variable that ranges over all
tuples in the result of some query
Can declare a cursor on a relation or query statement(which generates a relation)
DECLARE c CURSOR FOR ;
7/27/2019 8_DBApp
22/90
22
Cursors (cont.)
Can open a cursor, and repeatedly fetch a tuple thenmove the cursor, until all tuples have been retrieved
- Can use a special clause, called ORDER BY, in queries that areaccessed through a cursor, to control the order in which tuplesare returned
Fields in ORDER BY clause must also appear in SELECTclause- The ORDER BY clause, which orders answer tuples, is only
allowed in the context of a cursor
Can also modify/delete the tuple pointed to by a cursor
7/27/2019 8_DBApp
23/90
23
Opening and closing cursors
To use cursor c, we must issue the command:OPEN c;
- The query of c is evaluated, and c is set to point to the firsttuple of the result
When finished with c, issue command:CLOSE c;
7/27/2019 8_DBApp
24/90
24
Fetching tuples from a cursor
To get the next tuple from cursor c, issue command:FETCH FROM c INTO x1, x2, , xn ;
The xs are a list of variables, one for each component ofthe tuples referred to by c
cis moved automatically to the next tuple
7/27/2019 8_DBApp
25/90
25
Breaking cursor loops (1)
The usual way to use a cursor is to create a loop with aFETCH statement, and do something with each tuplefetched
A tricky point is how we get out of the loop when thecursor has no more tuples to deliver
7/27/2019 8_DBApp
26/90
26
Breaking cursor loops (2)
Each SQL operation returns a status, which is a 5-digitcharacter string- For example, 00000 = Everything OK,and 02000 = Failed to
find a tuple
We can get the value of the status in a variable calledSQLSTATE
7/27/2019 8_DBApp
27/90
27
Breaking cursor loops (3)
We may declare a condition, which is a boolean variablethat is true if and only if SQLSTATEhas a particularvalue
Example: We can declare condition NotFoundtorepresent 02000 by:
DECLARE NotFound CONDITION FOR
SQLSTATE 02000;
7/27/2019 8_DBApp
28/90
28
Breaking cursor loops (4)
The structure of a cursor loop is thus:cursorLoop: LOOP
...
FETCH c INTO ... ;
IF NotFound THEN LEAVE cursorLoop;
END IF;
...
END LOOP;
7/27/2019 8_DBApp
29/90
29
Cursor that gets names of sailors whovereserved a red boat, in alphabetical order
EXEC SQL DECLARE sinfo CURSOR FOR
SELECT S.sname
FORM Sailors S, Boats B, Reserves R
WHERE S.sid=R.sid AND R.bid=B.bid AND B.color=red
ORDER BY S.sname
Note that it is illegal to replace S.sname by, say, S.sid inthe ORDER BY clause because S.sid does not appear inSELECT!
7/27/2019 8_DBApp
30/90
30
Example: Embedding SQL in C
char SQLSTATE[6];EXEC SQL BEGIN DECLARE SECTION
char c_sname[20];
short c_minrating;
float c_age;
EXEC SQL END DECLARE SECTION
c_minrating = random();EXEC SQL DECLARE sinfo CURSOR FOR
SELECT S.sname, S.age
FROM Sailors S
WHERE S.rating > :c_minrating
ORDER BY S.sname;
EXEC SQL OPEN sinfo;do {
EXEC SQL FETCH sinfo INTO :c_sname; :c_age;
printf(%s is %d years old\n, c_sname, c_age);
} while (SQLSTATE != 02000); // 02000means NO DATA
EXEC SQL CLOSE sinfo;
7/27/2019 8_DBApp
31/90
31
Need for Dynamic SQL
Most applications use specific queries and modificationstatements to interact with the database- The DBMS compiles EXEC SQL statements into specific
procedure calls and produces an ordinary host-languageprogram that uses a library
What about the query the host language program readsin from the user, which doesnt know what it needs todo until it runs?- SQL query strings are not always known at compile time- E.g., spreadsheet or a graphical DBMS frontend allowsconstruction of SQL statements on-the-fly
7/27/2019 8_DBApp
32/90
32
Dynamic SQL example
char c_sqlstring[] =
{DELETE FROM Sailors WHERE rating>5}
EXEC SQL PREPARE readytogo FROM :c_sqlstring;
EXEC SQL EXECUTE readytogo;
7/27/2019 8_DBApp
33/90
33
Dynamic SQL constructs
Preparing a query:EXEC SQL PREPARE
FROM ;
Executing a query:EXEC SQL EXECUTE ;
Prepare= optimizequery Prepare once, execute many times
7/27/2019 8_DBApp
34/90
34
Example: A generic interface
EXEC SQL BEGIN DECLARE SECTION;
char query[MAX_LENGTH];
EXEC SQL END DECLARE SECTION;
while(1) {
/* issue SQL> prompt */
/* read users query into array query */
EXEC SQL PREPARE q FROM :query;
EXEC SQL EXECUTE q;
} q is an SQL variablerepresenting the optimized
form of whatever statement
is typed into :query
7/27/2019 8_DBApp
35/90
35
Execute-immediate
If we are only going to execute the query once, we cancombine the PREPARE and EXECUTE steps into one
Use:EXEC SQL EXECUTE IMMEDIATE ;
7/27/2019 8_DBApp
36/90
36
Example: Generic interface again
EXEC SQL BEGIN DECLARE SECTION;
char query[MAX_LENGTH];
EXEC SQL END DECLARE SECTION;
while(1) {/* issue SQL> prompt */
/* read users query into array query */
EXEC SQL EXECUTE IMMEDIATE :query;
}
7/27/2019 8_DBApp
37/90
37
Call-Level Interface (CLI)Alternative to embedding
7/27/2019 8_DBApp
38/90
38
Call-Level Interface (CLI)
Rather than modify compiler, add library with databasecalls (API)
Special standardized interface: procedures/objects Pass SQL strings from language, presents result sets in a
language-friendly way
SQL/CLI Suns JDBC: Java API Supposedly DBMS-neutral
- A drivertraps the calls and translates them into DBMS-specificcode
- Database can be across a network
7/27/2019 8_DBApp
39/90
39
JDBC architecture
Four architectural components:
Application- initiates and terminates connections- submits SQL statements
Driver manager- Loads JDBC driver
Driver- Connects to data source- Transmits requests and- Returns/translates results and error codes
Data source- Processes SQL statements
Will skip JDBCsince weve
already studied it.
I will leave these
slides in for yourreference though.
7/27/2019 8_DBApp
40/90
40
JDBC architecture (cont.)
Four types of drivers Bridge
- Translates SQL commands into non-native API- Ex: JDBC-ODBC bridge (code for ODBC and JDBC driver needs to be
available on each client)
Direct translation to native API via non-Java driver- Translates SQL commands to native API of data source- Needs OS-specific binary on each client
Network bridge- Sends commands over the network to a middleware server that talks to
the data source.- Needs only small JDBC driver at each client
Direct translation to native API via Java driver- Converts JDBC calls directly to network protocol used by DBMS- Needs DBMS-specific Java driver at each client
7/27/2019 8_DBApp
41/90
41
JDBC classes and interfaces
Steps to submit a database query
Load the JDBC driver Connect to the data source
Execute SQL statements
7/27/2019 8_DBApp
42/90
42
JDBC driver management
All drivers are managed by the DriverManager class Loading a JDBC driver
- In the Java codeClass.forName(oracle.jdbc.driver.OracleDriver);
Class.forName(com.mysql.jdbc.Driver);
-When starting the Java application-Djdbc.drivers=oracle.jdbc.driver
7/27/2019 8_DBApp
43/90
43
Connections in JDBC
We interact with a data source through sessions- Each connection identifies a logical session
JDBC URL:- Jdbc:.
Example:String url=jdbc:oracle:www.bookstore.com:3083;
Connection con;
try {
con = DriverManager.getConnection(url,userid,passwd);
} catch SQLException excpt { . . . }
// MySQL example:
DriverManager.getConnection(
"jdbc:mysql://localhost:3306/bookstore", //database name
"alee", // username
allowme"); // password
7/27/2019 8_DBApp
44/90
44
Connection class interface
public int getTransactionIsolation()
public void setTransactionIsolation(int level)- Sets isolation level for the current connection
public boolean getReadOnly()
public void setReadOnly(boolean b)- Specifies whether transactions in this connection are read-only
public boolean getAutoCommit()
public void setAutoCommit(boolean b)- If autocommit is set, then each SQL statement is considered its own
transaction
- Otherwise, a transaction is committed using commit(), or aborted usingrollback()
public boolean isClosed()
- Checks whether connection is still open
7/27/2019 8_DBApp
45/90
45
Executing SQL statements
Three different ways of executing SQL statements- Statement
Both static and dynamic SQL statements- PreparedStatement
Semi-static SQL statements- CallableStatement
Stored procedures PreparedStatement class
- Precompiled, parameterized SQL statements Structure is fixed Values of parameters are determined at run-time
7/27/2019 8_DBApp
46/90
46
Executing SQL statements (cont.)
String sql=INSERT INTO Sailors VALUES(?,?,?,?);
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.clearParameters();
pstmt.setInt(1, sid);
pstmt.setString(2, sname);pstmt.setInt(3, rating);
pstmt.setFloat(4, age);
// No rows are returned so use executeUpdate (insert, update, alter,
// delete)// Use executeQuery if it returns rows (select)
int numRows = pstmt.executeUpdate();
7/27/2019 8_DBApp
47/90
47
ResultSets
PreparedStatement.executeUpdate only returns thenumber of affected records
PreparedStatement.executeQuery returns data,encapsulated in a ResultSet object (a cursor)
ResultSet rs=pstmt.executeQuery(sql);
// rs is now a cursor
while (rs.next()) {
// process the data
}
7/27/2019 8_DBApp
48/90
48
ResultSets (cont.)
A ResultSet is a very powerful cursor
previous()- moves one row back
absolute(int num)- moves to the row with the specified number
relative(int num)- moves forward or backward
first() last()
7/27/2019 8_DBApp
49/90
49
Example: ResultSet
String query = SELECT ;
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
isbn = rs.getString(1);title = rs.getString(TITLE);
// process isbn and title
}
7/27/2019 8_DBApp
50/90
50
Matching Java and SQL data types
SQL Type Java class ResultSet get method
BIT Boolean getBoolean()
CHAR String getString()
VARCHAR String getString()
DOUBLE Double getDouble()FLOAT Double getDouble()
INTEGER Integer getInt()
REAL Double getFloat()
DATE Java.sql.Date getDate()
TIME Java.sql.Time getTime()TIMESTAMP Java.sql.TimeStamp getTimestamp()
7/27/2019 8_DBApp
51/90
51
JDBC: exceptions and warning
Most ofjava.sql can throw an SQLException if an erroroccurs (cf. SQLSTATE)
SQLWarning is a subclass of SQLException- Not as severe- They are not thrown and their existence has to be explicitly tested
7/27/2019 8_DBApp
52/90
52
Warning and exceptions (cont.)
try {
stmt=con.createStatement();
warning=con.getWarnings();
while (warning != null) {
// handle SQLWarnings
warning = warning.getNextWarning();}
con.clearWarnings();
stmt.executeUpdate(queryString);
warning = con.getWarnings();
}
catch (SQLException sqle) {
// handle the exception
}
7/27/2019 8_DBApp
53/90
53
Examining database metadata
DatabaseMetaData object gives information about thedatabase system and the catalog
DatabaseMetaData md = con.getMetaData();
// print information about the driverSystem.out.println(Name: + md.getDriverName() +
version: + md.getDriverVersion());
7/27/2019 8_DBApp
54/90
54
Database metadata (cont.)
DatabaseMetaData md = con.getMetaData();ResultSet trs=md.getTables(null,null,null,null);
String tableName;
while (trs.next()) {
tableName = trs.getString(TABLE_NAME);
System.out.println(Table: + tableName);
// prints all attributesResultSet crs = md.getColumns(null,null,tableName,null);
while (crs.next()) {
System.out.println(crs.getString(COLUMN_NAME) + );
}
// prints out the primary keys of this table
System.out.println(The keys of table + tableName + are:);
ResultSet krs = md.getPrimaryKeys(null,null,tableName);
while (krs.next()) {
System.out.println(krs.getString(COLUMN_NAME) + );
}
}
7/27/2019 8_DBApp
55/90
55
A (semi-)complete example
Connection con = // connectDriverManager.getConnection(url,login, passwd);
Statement stmt = con.createStatement(); // set up stmt
String query = SELECT name, rating FROM Sailors;
ResultSet rs = stmt.executeQuery(query);
try {
while (rs.next()) { // loop through result tuplesString s = rs.getString(name);
int n = rs.getInt(rating);
System.out.println(s + + n);
}
}
catch (SQLException ex) {
System.out.println(ex.getMessage() + +
ex.getSQLState() + +
ex.getErrorCode());
}
7/27/2019 8_DBApp
56/90
56
CLI Examples for C and Java
See a complete example each for both Java and C See DB.java and Bank1.java from an earlier lecture on
JDBC for Java
See cmysql.c for C
7/27/2019 8_DBApp
57/90
57
SQLJ
SQLJ should really be in the Embedded SQL section ofthis slide set, but I located it here so that you cancompare it with JDBC
Embedded SQL with Java
Preprocessor for SQLJ into Java Complements JDBC with a semi-static query model SQLJ (part of the SQL standard) versus embedded SQL(vendor-specific) [I am providing these slides for SQLJ, but we wont go
over them in class. Its an optional topic.]
7/27/2019 8_DBApp
58/90
58
SQLJ vs. JDBC
With SQLJ, compilers can perform syntax checks, strongtype checks, consistency of the query with the schema- All arguments always bound to the same variable
#sql = { SELECT name, rating INTO :name, :rating
FROM BooksWHERE sid = :sid;
}
- Compare to JDBCSid = rs.getInt(1);
if (sid==1)
sname1 = rs.getString(2);
else
sname2 = rs.getString(2);
7/27/2019 8_DBApp
59/90
59
SQLJ codeInt sid; Sting name; Int rating;
// 1. Declare the iterator class (cursor!)
#sql iterator Sailors(Int sid, String name, Int rating);
// 2. Instantiate an iterator object
Sailors sailors;
// 3. Initialize the iterator#sql sailors = {
SELECT sid, sname INTO :sid, :name
FROM Sailors
WHERE rating = :rating
};
// 4. Retrieve results
while (sailors.next()) {
System.out.println(sailors.sid + + sailors.sname));
}
// 5. Close the iterator object
sailors.close();
7/27/2019 8_DBApp
60/90
60
Corresponding JDBC code
PreparedStatement stmt = connection.prepareStatement(SELECT sid, sname FROM Sailors WHERE rating=?);
// set the parameter in the query and execute it
stmt.setInt(1, rating);
ResultSet rs = stmt.executeQuery();
// retrieve the results
while (rs.next()) {
System.out.println(rs.getInt(1) + + rs.getString(2));
}
7/27/2019 8_DBApp
61/90
61
SQLJ iterators
Two types of iterators (cursors) Named iterator
- Need both variable type and name, and then allows retrieval of columns by name- See example two slides ago
Positional iterator- Need only variable type, and then uses FETCH INTO construct#sql iterator Sailors(Int, String, Int);
Sailors sailors;
#sailors = . . .
while (true) {
#sql {FETCH :sailors INTO :sid, :name, :rating};
if (sailors.endFetch()) {
break;
}
// process the sailor
}
7/27/2019 8_DBApp
62/90
62
Stored Procedures
Alternative to Embedding and CLI
7/27/2019 8_DBApp
63/90
63
Stored Procedures
PSM (Persistent Stored Modules) allows us to storeprocedures as database schema elements (SQL:2003)
A stored procedure is- A program executed through a single SQL statement- Executed in the process space of the server- PSM = a mixture of conventional statements (if, while, etc.) and SQL
Advantages- Lets us do things we cannot do in SQL alone- Can encapsulate application logic while staying closeto the data- Reuse of application logic by different users- Avoid tuple-at-a-time return of records through cursors
Most DBMSs allow users to write stored procedures in asimple, general-purpose language (close to SQL)- A SQL/PSM standard is a representative
7/27/2019 8_DBApp
64/90
64
Basic PSM Form
CREATE PROCEDURE (
)
;
Function alternative:CREATE FUNCTION (
) RETURNS
;
7/27/2019 8_DBApp
65/90
65
Parameters in PSM
Unlike the usual name-type pairs in languages like C,PSM uses mode-name-type triples, where the mode canbe:
- IN= procedure uses value, does not change value- OUT= procedure changes, does not use- INOUT= both
7/27/2019 8_DBApp
66/90
66
Example: Stored procedure (next)
Lets write a procedure that takes two arguments b andp, and adds a tuple to Sells(bar, beer, price)that has bar= Joes Bar, beer = b, and price =p
- Used by Joe to add to his menu more easily
7/27/2019 8_DBApp
67/90
67
The procedure (definition)
CREATE PROCEDURE JoeMenu (
IN b CHAR(20),
IN p REAL
)
INSERT INTO Sells
VALUES(Joes Bar, b, p);
Parameters are both
read-only, not changed
The body a
single insertion
7/27/2019 8_DBApp
68/90
68
Invokingprocedures
Use SQL/PSM statement CALL, with the name of thedesired procedure and actual arguments
Example:CALL JoeMenu(Moosedrool, 5.00);
Functions used in SQL expressions wherever a value oftheir return type is appropriate
7/27/2019 8_DBApp
69/90
69
Kinds of PSM statements (1)
RETURN sets the return value of afunction- Unlike C, etc., RETURN doesnot terminate function execution
DECLARE used to declare localvariables BEGIN . . . ENDfor groups of statements
- Separate statements by semicolons Not surprising it requires most of the language
constructs in this language too. After all, you needthose to create functions as in any language powerfulenough to support functions!!!
7/27/2019 8_DBApp
70/90
70
Kinds of PSM statements (2)
Assignment statements:SET = ;- Example: SET b = Bud;
Statement labels: give a statement a label by prefixing aname and a colon
7/27/2019 8_DBApp
71/90
71
IF statements
Simplest form:IF THEN
END IF; Add ELSE if desired, as
IF . . . THEN . . . ELSE . . . END IF;
Add additional cases by ELSEIF :IF THEN ELSEIF THEN ELSEIF THEN ELSE END IF;
7/27/2019 8_DBApp
72/90
72
Example: IF
Lets rate bars by how many customers they have,based on Frequents(drinker,bar)- = 200 customers: popular
Function Rate(b)rates bar b
7/27/2019 8_DBApp
73/90
73
Example: IF (cont.)
CREATE FUNCTION Rate (IN b CHAR(20) )RETURNS CHAR(10)DECLARE cust INTEGER;
BEGIN
SET cust = (SELECT COUNT(*) FROM FrequentsWHERE bar = b);IF cust < 100 THEN RETURN unpopularELSEIF cust < 200 THEN RETURN averageELSE RETURN popularEND IF;
END;
Number of
customers of
bar b
Return occurs here, not at
one of the RETURN statements
7/27/2019 8_DBApp
74/90
74
Loops
Basic form:: LOOP
END LOOP;
Exit from a loop by:LEAVE
7/27/2019 8_DBApp
75/90
75
Example: Exiting a loop
loop1: LOOP
. . .
LEAVE loop1;
. . .
END LOOP;
If this statement is executed . . .
Control winds up here
7/27/2019 8_DBApp
76/90
76
Other loop forms
WHILE DO
END WHILE;
REPEAT UNTIL
END REPEAT;
7/27/2019 8_DBApp
77/90
77
1. Queries
General SELECT-FROM-WHERE queries are notpermitted in PSM
There are three ways to get the effect of a query:1. Queries producing one value can be the expression in an
assignment
2. Single-row SELECT . . . INTO3. Can use cursors naturally without EXEC SQL
7/27/2019 8_DBApp
78/90
78
Example: Assignment/Query
Using local variablep and Sells(bar, beer, price), wecan get the price Joe charges for Bud by:
SET p = (SELECT priceFROM Sells
WHERE bar = Joes BarAND
beer = Bud);
7/27/2019 8_DBApp
79/90
79
2. SELECT . . . INTO
Another way to get the value of a query that returnsone tuple is by placing INTO after theSELECT clause.
Example:SELECTprice INTOp
FROM Sells
WHERE bar =Joe
s Bar
AND
beer = Bud;
7/27/2019 8_DBApp
80/90
80
3. Cursor
Lets write a procedure that examines Sells(bar, beer,price), and raises by $1 the price of all beers at Joes Barthat are under $3
- Yes, we could write this as a simple UPDATE, but the detailsare instructive anyway
7/27/2019 8_DBApp
81/90
81
The needed declarations
CREATE PROCEDURE JoeGouge( )
DECLARE theBeer CHAR(20);
DECLARE thePrice REAL;
DECLARE NotFound CONDITION FORSQLSTATE 02000;
DECLARE c CURSOR FOR
(SELECT beer, price
FROM SellsWHERE bar = Joes Bar);
Used to hold
beer-price pairs
when fetching
through cursor c
Returns Joes menu
7/27/2019 8_DBApp
82/90
82
The procedure body
BEGIN
OPEN c;
menuLoop: LOOPFETCH c INTO theBeer, thePrice;
IF NotFound THEN LEAVE menuLoop END IF;
IF thePrice < 3.00 THENUPDATE Sells SET price = thePrice + 1.00
WHERE bar = Joes BarAND beer = theBeer;
END IF;END LOOP;
CLOSE c;
END;
Check if the recent
FETCH failed to
get a tuple
If Joe charges less than $3 forthe beer, raise its price at
Joes Bar by $1
7/27/2019 8_DBApp
83/90
83
More examples
CREATE PROCEDURE ShowNumReservations
SELECT S.sid, S.sname, COUNT(*)
FROM Sailors S, Reserves R
WHERE S.sid = R.sid
GROUP BY S.sid, S.sname
CREATE PROCEDURE IncreaseRating(
IN sailorId INTEGER, IN increase INTEGER)
UPDATE Sailors
SET rating = rating + increase
WHERE sid = sailorId
7/27/2019 8_DBApp
84/90
84
Stored procedures in any language
Stored procedures do not have to be written in SQLCREATE PROCEDURE TopSailors (IN num INTEGER)
LANGUAGE JAVAEXTERNAL NAME file://c:/storedProcs/rank.jar
7/27/2019 8_DBApp
85/90
85
Example: Calling stored procedures
EXEC SQL BEGIN DECLARE SECTION
Int sid;
Int rating;
EXEC SQL END DECLARE SECTION
// now increase the rating of this sailor
EXEC CALL IncreaseRating(:sid, :rating);
7/27/2019 8_DBApp
86/90
86
Ex: Calling stored procedures (cont.)
JDBC:
CallableStatement cstmt=con.prepareCall({call ShowSailors});
ResultSet rs=cstmt.executeQuery();
while (rs.next()) { . . . }
SQLJ:
#sql Iterator ShowSailors(. . .);
ShowSailors showsailors;#sql showsailors={CALL ShowSailors};
while (showsailors.next()) { . . . }
7/27/2019 8_DBApp
87/90
87
Example: function
CREATE FUNCTION rateSailor(IN sailorId INTEGER)
RETURNS INTEGER
DECALRE rating INTEGER
DECLARE numRes INTEGER
SET numRes = (SELECT COUNT(*)FROM Reserves R
WHERE R.sid = sailorId)
IF (numRes > 10)
THEN rating = 1;
ELSE rating = 0;
END IF;
RETURN rating;
7/27/2019 8_DBApp
88/90
88
Summary of SQL/PSM constructs
Local variables (DECLARE) RETURN values for FUNCTION Assign variables with SET Branches and loops
- IF () THEN ;ELSEIF () THEN ;
. . . ELSE ;
END IF;
- LOOP ;END LOOP;
Queries can be parts of expressions Can use cursors naturally without EXEC SQL
7/27/2019 8_DBApp
89/90
89
Summary
Embedded SQL allows execution of parameterized staticqueries within a host language
Dynamic SQL allows execution of completely ad hocqueries within a host language
Cursor mechanism allows retrieval of one record at atime and bridges impedance mismatch between hostlanguage and SQL
APIs such as JDBC introduce a layer of abstractionbetween application and DBMS
7/27/2019 8_DBApp
90/90
Summary (cont.)
SQLJ: static model, queries checked at compile-time Stored procedures execute application logic directly at
the server
SQL/PSM standard for writing stored procedures