0% found this document useful (0 votes)
5 views25 pages

DBMS Module 5

Chapter 3 of the document discusses Database Application Development, focusing on integrating SQL with general-purpose programming languages like C and Java through Embedded SQL and JDBC. It covers topics such as declaring variables, handling exceptions, using cursors for data retrieval, and the architecture of JDBC, which allows applications to interact with multiple databases without recompilation. The chapter also explains different types of JDBC drivers and their functionalities, emphasizing the flexibility and efficiency of using JDBC for database connectivity.

Uploaded by

chiragpatelmk46
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views25 pages

DBMS Module 5

Chapter 3 of the document discusses Database Application Development, focusing on integrating SQL with general-purpose programming languages like C and Java through Embedded SQL and JDBC. It covers topics such as declaring variables, handling exceptions, using cursors for data retrieval, and the architecture of JDBC, which allows applications to interact with multiple databases without recompilation. The chapter also explains different types of JDBC drivers and their functionalities, emphasizing the flexibility and efficiency of using JDBC for database connectivity.

Uploaded by

chiragpatelmk46
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Database Management System [18CS53]

[BCS403

Chapter 3: Database Application Development

2.1 Introduction
We often encounter a situations in which we need the greater flexibility of a general-purpose
programming language in addition to the data manipulation facilities provided by SQL.For example,
we may want to integrate a database applications with GUI or we may want to integrate with other
existing applications.

2.2 Accessing Databases from applications


SQL commands can be executed from within a program in a host language such as C or Java. A
language to which SQL queries are embedded are called Host language.

2.2.1 Embedded SQL

The use of SQL commands within a host language is called Embedded SQL. Conceptually,
embedding SQL commands in a host language program is straight forward. SQL statements can be
used wherever a statement in the host language is allowed. SQL statements must be clearly marked
so that a preprocessor can deal with them before invoking the compiler for the host language. Any
host language variable used to pass arguments into an SQL command must be declared in SQL.
There are two complications:
1. Data types recognized by SQL may not be recognized by the host language and vice versa
- This mismatch is addressed by casting data values appropriately before passing them to or
from SQL commands.
2. SQL is set-oriented
- Addressed using cursors

Declaring Variables and Exceptions

SQL statements can refer to variables defined in the host program. Such host language variables
must be prefixed by a colon(:) in SQL statements and be declared between the commands

EXEC SQL BEGIN DECLARE SECTION and EXEC SQL END DECLARE SECTION

page 45
Database Management System [18CS53]
[BCS403

The declarations are similar to C, are separated by semicolons. For example, we can declare
variables c_sname, c_sid, c_rating, and c_age (with the initial c used as a naming convention to
emphasize that these are host language variables) as follows:
EXEC SQL BEGIN DECLARE SECTION

char c_sname[20];
long c_sid;
short c_rating;
float c_age;
EXEC SQL END DECLARE SECTION

The first question that arises is which SQL types correspond to the various C types, since we have
just declared a collection of C variables whose values are intended to be read (and possibly set) in
an SQL run-time environment when an SQL statement that refers to them is executed. The SQL-92
standard defines such a correspondence between the host language types and SQL types for a
number of host languages. In our example, c_sname has the type CHARACTER(20) when referred
to in an SQL statement, c_sid has the type INTEGER, crating has the type SMALLINT, and c_age
has the type REAL.

We also need some way for SQL to report what went wrong if an error condition arises when
executing an SQL statement. The SQL-92 standard recognizes two special variables for reporting
errors, SQLCODE and SQLSTATE.
SQLCODE is the older of the two and is defined to return some negative value when an
error condition arises, without specifying further just what error a particular negative
integer denotes.
SQLSTATE, introduced in the SQL-92 standard for the first time, associates predefined
values with several common error conditions, thereby introducing some uniformity to how
errors are reported.
One of these two variables must be declared. The appropriate C type for SQLCODE is long and the
appropriate C type for SQLSTATE is char [6] , that is, a character string five characters long.

Embedding SQL statements


All SQL statements embedded within a host program must be clearly marked with the details
dependent on the host language. In C, SQL statements must be prefixed by EXEC SQL. An SQL
statement can essentially appear in any place in the host language program where a host language
statement can appear.
Example: The following embedded SQL statement inserts a row, whose column values are based
on the values of the host language variables contained in it, into the sailors relation
EXEC SQL INSERT INTO sailors VALUES (:c_sname, :c_sid, :c_rating,:c_age);

page 46
Database Management System [18CS53]
[BCS403

The SQLSTATE variable should be checked for errors and exceptions after each Embedded SQL
statement.SQL provides the WHENEVER command to simplify this task:
EXEC SQL WHENEVER [SQLERROR | NOT FOUND ] [CONTINUE|GOTO stmt]
If SQLERROR is specified and the value of SQLSTATE indicates an exception, control is transferred
to stmt, which is presumably responsible for error and exception handling. Control is also transferred
to stmt if NOT FOUND is specified and the value of SQLSTATE is 02000, which denotes NO DATA.

2.2.2 Cursors
A major problem in embedding SQL statements in a host language like C is that an impedance
mismatch occurs because SQL operates on sets of records, whereas languages like C do not cleanly
support a set-of-records abstraction. The solution is to essentially provide a mechanism thatallows
us to retrieve rows one at a time from a relation- this mechanism is called a cursor
We can declare a cursor on any relation or on any SQL query. Once a cursor is declared, we can
open it (positions the cursor just before the first row)
Fetch the next row
Move the cursor (to the next row,to the row after the next n, to the first row or previous row
etc by specifying additional parameters for the fetch command)
Close the cursor
Cursor allows us to retrieve the rows in a table by positioning the cursor at a particular row and
reading its contents.
Basic Cursor Definition and Usage
Cursors enable us to examine, in the host language program, a collection of rows computed by an
Embedded SQL statement:
We usually need to open a cursor if the embedded statement is a SELECT. we can avoid
opening a cursor if the answer contains a single row
INSERT, DELETE and UPDATE statements require no cursor. some variants of DELETE
and UPDATE use a cursor.
Examples:
i) Find the name and age of a sailor, specified by assigning a value to the host variable c_sid,
declared earlier
EXEC SQL SELECT s.sname,s.age
INTO :c_sname, :c_age
FROM Sailaor s
WHERE s.sid=:c.sid;

page 47
Database Management System [18CS53]
[BCS403

The INTO clause allows us assign the columns of the single answer row to the host variable
c_sname and c_age. Therefore, we do not need a cursor to embed this query in a host language
program.

ii) Compute the name and ages of all sailors with a rating greater than the current value of the host
variable c_minrating
SELECT s.sname,s.age
FROM sailors s WHERE s.rating>:c_minrating;
The query returns a collection of rows. The INTO clause is inadequate. The solution is to use a
cursor:
DECLARE sinfo CURSOR FOR
SELECT s.sname,s.age
FROM sailors s
WHERE s.rating>:c_minrating;
This code can be included in a C program and once it is executed, the cursor sinfo is defined.
We can open the cursor by using the syntax:
OPEN sinfo;

with it.When the cursor is opened, it is positioned just before the first row.
We can use the FETCH command to read the first row of cursor sinfo into host language variables:
FETCH sinfo INTO :c_sname, :c_age;
When the FETCH statement is executed, the cursor is positioned to point at the next row and the
column values in the row are copied into the corresponding host variables. By repeatedly executing
this FETCH statement, we can read all the rows computed by the query, one row at time.
When we are done with a cursor, we can close it:
CLOSE sinfo;
iii) To retrieve the name, address and salary of an employee specified by the variable ssn

page 48
Database Management System [18CS53]
[BCS403

Properties of Cursors
The general form of a cursor declaration is:
DECLARE cursorname [INSENSITIVE] [SCROLL] CURSOR
[WITH HOLD]
FOR some query
[ORDER BY order-item-list ]
[FOR READ ONLY I FOR UPDATE ]
A cursor can be declared to be a read-only cursor (FOR READ ONLY) or updatable cursor (FOR
UPDATE).If it is updatable, simple variants of the UPDATE and DELETE commands allow us to
update or delete the row on which the cursor is positioned. For example, if sinfo is an updatable
cursor and open, we can execute the following statement:
UPDATE Sailors S
SET S.rating = S.rating -1
WHERE CURRENT of sinfo;
A cursor is updatable by default unless it is a scrollable or insensitive cursor in which case it is read-
only by default.

If the keyword SCROLL is specified, the cursor is scrollable, which means that variants of the
FETCH command can be used to position the cursor in very flexible ways; otherwise, only the basic
FETCH command, which retrieves the next row, is allowed

If the keyword INSENSITIVE is specified, the cursor behaves as if it is ranging over a private copy
of the collection of answer rows. Otherwise, and by default, other actions of some transaction could
modify these rows, creating unpredictable behavior.

A holdable cursor is specified using the WITH HOLD clause, and is not closed when the transaction
is committed.

Optional ORDER BY clause can be used to specify a sort order. The order-item-list is a list of order-
items. An order-item is a column name, optionally followed by one of the keywords ASC or DESC
Every column mentioned in the ORDER BY clause must also appear in the select-list of the query
associated with the cursor; otherwise it is not clear what columns we should sort on

ORDER BY minage ASC, rating DESC

The answer is sorted first in ascending order by minage, and if several rows have the same minage
value, these rows are sorted further in descending order by rating

page 49
Database Management System [18CS53]
[BCS403

Rating minage

8 25.5

3 25.5

7 35.0
Dynamic SQL
Dynamic SQL Allow construction of SQL statements on-the-fly. Consider an application such as a
spreadsheet or a graphical front-end that needs to access data from a DBMS. Such an application
must accept commands from a user and, based on what the user needs, generate appropriate SQL
statements to retrieve the necessary data. In such situations, we may not be able to predict in
advance just what SQL statements need to be executed. SQL provides some facilities to deal with
such situations; these are referred to as Dynamic SQL.
Example:

char c_sqlstring[] = {"DELETE FROM Sailors WHERE rating>5"};


EXEC SQL PREPARE readytogo FROM :csqlstring;
EXEC SQL EXECUTE readytogo;
The first statement declares the C variable c_sqlstring and initializes its value to the string
representation of an SQL command
The second statement results in this string being parsed and compiled as an SQL command,
with the resulting executable bound to the SQL variable readytogo
The third statement executes the command

2.3 An Introduction to JDBC


Embedded SQL enables the integration of SQL with a general-purpose programming language. A
DBMS-specific preprocessor transforms the Embedded SQL statements into function calls in the
host language. The details of this translation vary across DBMSs, and therefore even though the
source code can be compiled to work with different DBMSs, the final executable works only with one
specific DBMS.
ODBC and JDBC, short for Open DataBase Connectivity and Java DataBase Connectivity, also
enable the integration of SQL with a general-purpose programming language.

In contrast to Embedded SQL, ODBC and JDBC allow a single executable to access
different DBMSs Without recompilation.

page 50
Database Management System [18CS53]
[BCS403

While Embedded SQL is DBMS-independent only at the source code level, applications
using ODBC or JDBC are DBMS-independent at the source code level and at the level of the
executable
In addition, using ODBC or JDBC, an application can access not just one DBMS but several
different ones simultaneously
ODBC and JDBC achieve portability at the level of the executable by introducing an extra
level of indirection
All direct interaction with a specific DBMS happens through a DBMS-specific driver.

A driver is a software program that translates the ODBC or JDBC calls into DBMS-specific calls.
Drivers are loaded dynamically on demand since the DBMSs the application is going to access
are known only at run-time. Available drivers are registered with a driver manager a driver does
not necessarily need to interact with a DBMS that understands SQL. It is sufficient that the driver
translates the SQL commands from the application into equivalent commands that the DBMS
understands.
An application that interacts with a data source through ODBC or JDBC selects a data source,
dynamically loads the corresponding driver, and establishes a connection with the data source.
There is no limit on the number of open connections. An application can have several open
connections to different data sources. Each connection has transaction semantics; that is,
changes from one connection are visible to other connections only after the connection has
committed its changes. While a connection is open, transactions are executed by submitting
SQL statements, retrieving results, processing errors, and finally committing or rolling back. The
application disconnects from the data source to terminate the interaction.

2.3.1 Architecture
The architecture of JDBC has four main components:

Application
Driver manager
Drivers
Data sources

page 51
Database Management System [18CS53]
[BCS403

Application

initiates and terminates the connection with a data source


sets transaction boundaries, submits SQL statements and retrieves the results

Driver manager

Load JDBC drivers and pass JDBC function calls from the application to the correct driver
Handles JDBC initialization and information calls from the applications and can log all
function calls
Performs some rudimentary error checking

Drivers

Establishes the connection with the data source


Submits requests and returns request results
Translates data, error formats, and error codes from a form that is specific to the data source
into the JDBC standard

Data sources

Processes commands from the driver and returns the results

Drivers in JDBC are classified into four types depending on the architectural relationship between
the application and the data source:

Type I Bridges:
This type of driver translates JDBC function calls into function calls of another API that is not
native to the DBMS.
An example is a JDBC-ODBC bridge; an application can use JDBC calls to access an
ODBC compliant data source. The application loads only one driver, the bridge.
Advantage:
it is easy to piggyback the application onto an existing installation, and no new
drivers have to be installed.
Drawbacks:
The increased number of layers between data source and application affects
performance
the user is limited to the functionality that the ODBC driver supports.

page 52
Database Management System [18CS53]
[BCS403

Type II Direct Translation to the Native API via Non-Java Driver:


This type of driver translates JDBC function calls directly into method invocations of the API
of one specific data source.
The driver is usually ,written using a combination of C++ and Java; it is dynamically
linked and specific to the data source.
Advantage
This architecture performs significantly better than a JDBC-ODBC bridge.
Disadvantage
The database driver that implements the API needs to be installed on each
computer that runs the application.
Type III~~Network Bridges:
The driver talks over a network to a middleware server that translates the JDBC requests
into DBMS-specific method invocations.
In this case, the driver on the client site is not DBMS-specific.
The JDBC driver loaded by the application can be quite small, as the only functionality it
needs to implement is sending of SQL statements to the middleware server.
The middleware server can then use a Type II JDBC driver to connect to the data source.
Type IV-Direct Translation to the Native API via Java Driver:
Instead of calling the DBMS API directly, the driver communicates with the DBMS
through Java sockets
In this case, the driver on the client side is written in Java, but it is DBMS-specific. It
translates JDBC calls into the native API of the database system.
This solution does not require an intermediate layer, and since the implementation is all
Java, its performance is usually quite good.

2.4 JDBC CLASSES AND INTERFACES


JDBC is a collection of Java classes and interfaces that enables database access from programs
written in the Java language. It contains methods for connecting to a remote data source, executing
SQL statements, examining sets of results from SQL statements, transaction management, and
exception handling.
The classes and interfaces are part of the java.sql package. JDBC 2.0 also includes the javax.sql
package, the JDBC Optional Package. The package javax.sql adds, among other things, the
capability of connection pooling and the Row-Set interface.

page 53
[18CS53]
Database Management System [BCS403

2.4.1 JDBC Driver Management


In JDBC, data source drivers are managed by the Drivermanager class, which maintains a list of all
currently loaded drivers. The Drivermanager class has methods registerDriver, deregisterDriver, and
getDrivers to enable dynamic addition and deletion of drivers.
The first step in connecting to a data source is to load the corresponding JDBC driver. The following
Java example code explicitly loads a JDBC driver:
Class.forName("oracle/jdbc.driver.OracleDriver");
There are two other ways ofregistering a driver. We can include the driver with -Djdbc.
drivers=oracle/jdbc. driver at the command line when we start the Java application. Alternatively, we
can explicitly instantiate a driver, but this method is used only rarely, as the name of the driver has
to be specified in the application code, and thus the application becomes sensitive to changes at the
driver level.
After registering the driver, we connect to the data source.

2.4.2 Connections
A session with a data source is started through creation of a Connection object; Connections are
specified through a JDBC URL, a URL that uses the jdbc protocol. Such a URL has the form
jdbc:<subprotocol>:<otherParameters>

String uri = .. jdbc:oracle:www.bookstore.com:3083..


Connection connection;
try
{
Connection connection =
DriverManager.getConnection(urI, userId,password);
}
catch(SQLException excpt)
{
System.out.println(excpt.getMessageO);
return;
}

Program code: Establishing a Connection with JDBC


In JDBC, connections can have different properties. For example, a connection can specify the
granularity of transactions. If autocommit is set for a connection, then each SQL statement is

https://vtucode.in page 54
Database Management System [18CS53]
BCS403

considered to be its own transaction. If autocommit is off, then a series of statements that compose
a transaction can be committed using the commit() method of the Connection class, or aborted
using the rollback() method. The Connection class has methods to set the autocommit mode
(Connection. setAutoCommit) and to retrieve the current autocommit mode (getAutoCommit). The
following methods are part of the Connection interface and permit setting and getting other
properties:
public int getTransactionIsolation() throws SQLException and
public void setTransactionlsolation(int 1) throws SQLException.
- These two functions get and set the current level of isolation for transactions handled
in the current connection. All five SQL levels of isolation are possible, and argument l can
be set as follows:
- TRANSACTION_NONE
- TRANSACTION_READ_UNCOMMITTED
- TRANSACTION_READ_COMMITTED
- TRANSACTION_REPEATABLE_READ
- TRANSACTION_SERIALIZABLE
public boolean getReadOnlyO throws SQLException and
public void setReadOnly(boolean readOnly) throws SQLException.
- These two functions allow the user to specify whether the transactions executecl through
this connection are rcad only.
public boolean isClosed() throws SQLException.
- Checks whether the current connection has already been closed.
setAutoCommit and get AutoCommit.
In case an application establishes many different connections from different parties (such as a Web
server), connections are often pooled to avoid this overhead. A connection pool is a set of
established connections to a data source. Whenever a new connection is needed, one of the
connections from the pool is used, instead of creating a new connection to the data source.

2.4.3 Executing SQL Statements


JDBC supports three different ways of executing statements:
Statement
PreparedStatement, and
CallableStatement.
The Statement class is the base class for the other two statement classes. It allows us to query the
data source with any static or dynamically generated SQL query.

page 55
Database Management System [18CS53]
BCS403

The PreparedStatement class dynamically generates precompiled SQL statements that can be
used several times; these SQL statements can have parameters, but their structure is fixed when
the PreparedStatement object is created.
/ / initial quantity is always zero
String sql = "INSERT INTO Books VALUES('?, 7, '?, ?, 0, 7)";
PreparedStatement pstmt = con.prepareStatement(sql);
/ / now instantiate the parameters with values
/ / a,ssume that isbn, title, etc. are Java variables that
/ / contain the values to be inserted
pstmt.clearParameters() ;
pstmt.setString(l, isbn);
pstmt.setString(2, title);
pstmt.setString(3, author);
pstmt.setFloat(5, price);
pstmt.setInt(6, year);
int numRows = pstmt.executeUpdate();

program code: SQL Update Using a PreparedStatement Object

The SQL query specifies the query string, but uses ''?' for the values of the parameters, which are
set later using methods setString, setFloat,and setlnt. The placeholders can be used anywhere
in SQL statements where they can be replaced with a value. Examples of places where they can
appear include the WHERE clause (e.g., 'WHERE author=?'), or in SQL UPDATE and INSERT
statements. The method setString is one way to set a parameter value; analogous methods are
available for int, float, and date. It is good style to always use clearParameters() before setting
parameter values in order to remove any old data.

There are different ways of submitting the query string to the data source. In the example, we used
the executeUpdate command, which is used if we know that the SQL statement does not return
any records (SQL UPDATE, INSERT,ALTER, and DELETE statements). The executeUpdate
method returns
- an integer indicating the number of rows the SQL statement modified;
- 0 for successful execution without modifying any rows.
The executeQuery method is used if the SQL statement returns data, such as in a regular SELECT
query. JDBC has its own cursor mechanism in the form of a ResultSet object.

page 56
Database Management System [18CS53]
BCS403

2.4.4 ResultSets
ResultSet cursors in JDBC 2.0 are very powerful; they allow forward and reverse scrolling and in-
place editing and insertions. In its most basic form, the ResultSet object allows us to read one row
of the output of the query at a time. Initially, the ResultSet is positioned before the first row, and we
have to retrieve the first row with an explicit call to the next() method. The next method returns false
if there are no more rows in the query answer, and true other\vise. The code fragment shown below
illustrates the basic usage of a ResultSet object:
ResultSet rs=stmt.executeQuery(sqlQuery);
/ / rs is now a cursor
/ / first call to rs.nextO moves to the first record
/ / rs.nextO moves to the next row
String sqlQuery;
ResultSet rs = stmt.executeQuery(sqlQuery)
while (rs.next())
{
/ / process the data
}
While next () allows us to retrieve the logically next row in the query answer, we can move about in
the query answer in other ways too:
previous() moves back one row.
absolute(int num) moves to the row with the specified number.
relative(int num) moves forward or backward (if num is negative) relative to the current
position. relative (-1) has the same effect as previous.
first() moves to the first row, and last() moves to the last row.

Matching Java and SQL Data Types


In considering the interaction of an application with a data source, the issues we encountered in the
context of Embedded SQL (e.g., passing information between the application and the data source
through shared variables) arise again. To deal with such issues, JDBC provides special data types
and specifies their relationship to corresponding SQL data types. Table 2.4.4 shows the accessor
methods in a ResultSet object for the most common SQL datatypes.

With these accessor methods, we can retrieve values from the current row of the query result
referenced by the ResultSet object. There are two forms for each accessor method. One method
retrieves values by column index, starting at one, and the other retrieves values by column name.

page 57
Database Management System [18CS53]
BCS403

The following example shows how to access fields of the current ResultSet row using accesssor
methods.
ResultSet rs=stmt.executeQuery(sqIQuery);

String sqlQuerYi
ResultSet rs = stmt.executeQuery(sqIQuery)
while (rs.nextO)
{
isbn = rs.getString(l);
title = rs.getString(" TITLE");
/ / process isbn and title
}

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()

Table 2.4.4 : Reading SQL Datatypes from a ResultSet Object

2.4.5 Exceptions and Warnings


Similar to the SQLSTATE variable, most of the methods in java. sql can throw an exception of the
type SQLException if an error occurs. The information includes SQLState, a string that describes
the error (e.g., whether the statement contained an SQL syntax error). In addition to the standard
getMessage() method inherited from Throwable, SQLException has two additional methods that
provide further information, and a method to get (or chain) additional exceptions:
public String getSQLState() returns an SQLState identifier based on the SQL:1999
specification
public int getErrorCode () retrieves a vendor-specific error code.

page 58
[18CS53]
Database Management System BCS403

public SQLException getNextExceptionO gets the next exception in a chain of exceptions


associated with the current SQLException object.

An SQLWarning is a subclass of SQLException. Warnings are not as severe as errors and the
program can usually proceed without special handling of warnings. Warnings are not thrown like
other exceptions, and they are not caught as part of the try-catch block around a java.sql statement.
We need to specifically test whether warnings exist. Connection, Statement, and ResultSet
objects all have a getWarnings() method with which we can retrieve SQL warnings if they exist.
Duplicate retrieval of warnings can be avoided through clearWarnings(). Statement objects clear
warnings automatically on execution of the next statement; ResultSet objects clear warnings every
time a new tuple is accessed.
Typical code for obtaining SQLWarnings looks similar to the code shown below:
try
{
stmt = con.createStatement();
warning = con.getWarnings();
while( warning != null)
{
/ / handleSQLWarnings / / code to process warning
warning = warning.getNextWarningO; / /get next warning
}
con.clear\Varnings() ;
stmt.executeUpdate( queryString );
warning = stmt.getWarnings();
while( warning != null)
{
/ / handleSQLWarnings / / code to process warning
warning = warning.getNextWarningO; / /get next warning
}
} / / end try

catch ( SQLException SQLe)


{
/ / code to handle exception
} / / end catch

page 59
[18CS53]
Database Management System [BCS403

2.4.6 Examining Database Metadata


We can use the DatabaseMetaData object to obtain information about the database system itself,
as well as information from the database catalog. For example, the following code fragment shows
how to obtain the name and driver version of the JDBC driver:
Databa..seMetaData md = con.getMetaD<Lta():
System.out.println("Driver Information:");
System.out.println("Name:" + md.getDriverNameO
+ "; version:" + mcl.getDriverVersion());
The DatabaseMetaData object has many more methods (in JDBC 2.0, exactly 134). Some of the
methods are:
public ResultSet getCatalogs() throws SqLException. This function returns a
ResultSet that can be used to iterate over all public int getMaxConnections()
throws SqLException the catalog relations.This function returns the maximum
number of connections possible.
Example: code fragment that examines all database metadata
DatabaseMetaData dmd = con.getMetaDataO;
ResultSet tablesRS = dmd.getTables(null,null,null,null);
string tableName;
while(tablesRS.next())
{
tableNarne = tablesRS .getString("TABLE_NAME");
/ / print out the attributes of this table
System.out.println("The attributes of table"
+ tableName + " are:");
ResultSet columnsRS = dmd.getColums(null,null,tableName, null);
while (columnsRS.next())
{
System.out.print(colummsRS.getString("COLUMN_NAME")
+" ");
}
/ / print out the primary keys of this table
System.out.println("The keys of table" + tableName + " are:");
ResultSet keysRS = dmd.getPrimaryKeys(null,null,tableName);
while (keysRS. next ())
{
System.out.print(keysRS.getStringC'COLUMN_NAME") +" ");
}

page 60
Database Management System [18CS53]
[BCS403

}
7 steps for jdbc :
1. Import the package
-- import java.sql.*;
2. Load and register the driver
--class.forname();
3. Establish the connection
-- Connection con;
4. Create a Statement object
-- Statement st;
5. Execute a query
-- st.execute();
6. Process the result
7. Close the connection

Step 2: load the corresponding JDBC driver


Class.forName("oracle/jdbc.driver.OracleDriver");
Step 3: create a session with data source through creation of Connection object.
Connection connection = DriverManager.getConnection(database_urI,
userId, password);
EX: Connection con= DriverManager.getConnection
("jdbc:oracle:thin:@localhost:1521:xesid","system","ambika");
Step 4:create a statement object
JDBC supports three different ways of executing statements:
- Statement
- PreparedStatement and
- CallableStatement.
The Statement class is the base class for the other two statement classes. It allows us to
query the data source with any static or dynamically generated SQL query.
The PreparedStatement class dynamically generates precompiled SQL statements that
can be used several times
CallableStatement are used to call stored procedures from JDBC. CallableStatement is a
subclass of PreparedStatement and provides the same functionality.
Example:
Statement st=con.createStatement();
Step 5: executing a query

page 61
Database Management System [18CS53]
[BCS403

ResultSet rs=st.executeQuery(query);

Step 6: process the result

String sname=rs.getString(2);

System.out.println(sname);

Step 7: close the connection

con.close();

2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12 SQLJ

page 62
[18CS53]
Database Management System [BCS403

2.5 SQLJ: SQL-JAVA


SQLJ enables applications programmers to embed SQL statements in Java code in a way that is
compatible with the Java design philosophy
Example: SQLJ code fragment that selects records from the Books table that match a given author.

String title; Float price; String author;

#sql iterator Books (String title, Float price);

Books books;

#sql books = {

SELECT title, price INTO :titIe, :price

FROM Books WHERE author = :author

};

while (books.next()) {

System.out.println(books.title() + ", " + books.price());

books.close() ;

All SQLJ statements have the special prefix #sql. In SQLJ, we retrieve the results of SQL queries
with iterator objects, which are basically cursors. An iterator is an instance of an iterator class.
Usage of an iterator in SQLJ goes through five steps:
1. Declare the Iterator Class: In the preceding code, this happened through the statement
#sql iterator Books (String title, Float price);
This statement creates a new Java class that we can use to instantiate objects.
2. Instantiate an Iterator Object from the New Iterator Class:

We instantiated our iterator in the statement Books books;.

3. Initialize the Iterator Using a SQL Statement:


In our example, this happens through the statement #sql books =....
4. Iteratively, Read the Rows From the Iterator Object:
This step is very similar to reading rows through a ResultSet object in JDBC.
5. Close the Iterator Object.

page 63
[18CS53]
Database Management System [BCS403

There are two types of iterator classes:


named iterators
positional iterators
For named iterators, we specify both the variable type and the name of each column of the iterator.
This allows us to retrieve individual columns by name. This method is used in our example.
For positional iterators, we need to specify only the variable type for each column of the iterator. To
access the individual columns of the iterator, we use a FETCH ... INTO construct, similar to
Embedded SQL
We can make the iterator a positional iterator through the following statement:

#sql iterator Books (String, Float);

We then retrieve the individual rows from the iterator as follows:

while (true)

#sql { FETCH :books INTO :title, :price, };

if (books.endFetch())

{ break: }

/ / process the book

2.6 STORED PROCEDURES


Stored procedure is a set of logical group of SQL statements which are grouped to perform a
specific task.

Benefits :

reduces the amount of information transfer between client and database server

Compilation step is required only once when the stored procedure is created. Then after it
does not require recompilation before executing unless it is modified and reutilizes the same
execution plan whereas the SQL statements need to be compiled every time whenever it is
sent for execution even if we send the same SQL statement every time

It helps in re usability of the SQL code because it can be used by multiple users and by
multiple clients since we need to just call the stored procedure instead of writing the same
SQL statement every time. It helps in reducing the development time

page 64
Database Management SystemBCS403
[18CS53]
[BCS403BCS403]

Syntax:

Create or replace procedure <procedure Name> [(arg1 datatype, arg2 datatype)]

Is/As

<declaration>

Begin

<SQL Statement>

Exception

End procedurename;

2.6.1 Creating a Simple Stored Procedure

Consider the following schema:

Student(usn:string,sname:string)

Let us now write a stored procedure to

create or replace procedure ss

is

stu_cnt int;

begin

select count(*) into stu_cnt from students where sname='AKSHAY';

dbms_output.put_line('the count of student is :' || stu_cnt);

end ss;

Stored procedures can also have parameters. These parameters have to be valid SQL types, and
have one of three different modes: IN, OUT, or INOUT.

IN parameters are arguments to the stored procedure

OUT parameters are returned from the stored procedure; it assigns values to all OUT
parameters that the user can process

INOUT parameters combine the properties of IN and OUT parameters: They contain values
to be passed to the stored procedures, and the stored procedure can set their values as
return values

page 65
Database Management System [18CS53]
[BCS403

Example:

CREATE PROCEDURE Addlnventory (

IN book_isbn CHAR(lO),

IN addedQty INTEGER)

UPDATE Books SET qty_in_stock = qtyjn_stock + addedQty

WHERE bookjsbn = isbn

In Embedded SQL, the arguments to a stored procedure are usually variables in the host language.
For example, the stored procedure AddInventory would be called as follows:
EXEC SQL BEGIN DECLARE SECTION
char isbn[lO];
long qty;
EXEC SQL END DECLARE SECTION
/ / set isbn and qty to some values
EXEC SQL CALL AddInventory(:isbn,:qty);

Stored procedures enforce strict type conformance: If a parameter is of type INTEGER, it cannot be
called with an argument of type VARCHAR.

Procedures without parameters are called static procedures and with parameters are called
dynamic procedures.

Example: stored procedure with parameter

create or replace procedure emp(Essn int)

as

eName varchar(20);

begin

select fname into eName from employee where ssn=Essn and dno=5;

dbms_output.put_line(' the employee name is :'||Essn ||eName);

end emp;

2.6.2 Calling Stored Procedures


Stored procedures can be called in interactive SQL with the CALL statement:

CALL storedProcedureName(argl, arg2, .. ,argN);

page 66
Database Management System [18CS53]
[BCS403

Calling Stored Procedures from JDBC


We can call stored procedures from JDBC using the CallableStatment class.A stored procedure
could contain multiple SQL statements or a series of SQL statements-thus, the result could be many
different ResultSet objects.We illustrate the case when the stored procedure result is a single
ResultSet.
CallableStatement cstmt= con. prepareCall(" {call ShowNumberOfOrders}");
ResultSet rs = cstmt.executeQuery();
while (rs.next())
Calling Stored Procedures from SQLJ
The stored procedure 'ShowNumberOfOrders' is called as follows using SQLJ:

/ / create the cursor class

#sql Iterator CustomerInfo(int cid, String cname, int count);

/ / create the cursor

CustomerInfo customerinfo;

/ / call the stored procedure

#sql customerinfo = {CALL ShowNumberOfOrders};

while (customerinfo.next()

System.out.println(customerinfo.cid() + "," +

customerinfo.count()) ;

2.6.3 SQL/PSM

SQL/Persistent Stored Modules is an ISO standard mainly defining an extension of SQL with
procedural language for use in stored procedures.

In SQL/PSM, we declare a stored procedure as follows:

CREATE PROCEDURE name (parameter1,... , parameterN)

local variable declarations

procedure code

page 67
Database Management System [18CS53]
[BCS403

We can declare a function similarly as follows:

CREATE FUNCTION name (parameterl, ... , parameterN)

RETURNS sqIDataType

local variable declarations

function code;

Example:

CREATE FUNCTION RateCustomer (IN custId INTEGER, IN year INTEGER)

RETURNS INTEGER

DECLARE rating INTEGER;

DECLARE numOrders INTEGER;

SET numOrders = (SELECT COUNT(*) FROM Orders 0 WHERE O.tid = custId);

IF (numOrders> 10) THEN rating=2;

ELSEIF (numOrders>5) THEN rating=1;

ELSE rating=O;

END IF;

RETURN rating;

We can declare local variables using the DECLARE statement. In our example, we declare two
local variables: 'rating', and 'numOrders'.

PSM/SQL functions return values via the RETURN statement. In our example, we return the
value of the local variable 'rating'.

We can assign values to variables with the SET statement. In our example, we assigned the
return value of a query to the variable 'numOrders'.

SQL/PSM has branches and loops. Branches have the following form:

IF (condition) THEN statements;

ELSEIF statements;

ELSEIF statements;

ELSE statements;

END IF

Loops are of the form

page 68
[18CS53]
Database Management System BCS403]

LOOP

statements:

END LOOP

Queries can be used as part of expressions in branches; queries that return a single value can be
assigned to variables.We can use the same cursor statements as in Embedded SQL (OPEN,
FETCH, CLOSE), but we do not need the EXEC SQL constructs, and variables do not have to be
prefixed by a colon ':'.

999999999 page 69

You might also like