PreparedStatement

G

gk

Please see this ..

http://java.sun.com/j2se/1.4.2/docs/api/java/sql/PreparedStatement.html

PreparedStatement : An object that represents a precompiled SQL
statement.

"precompiled SQL statement" ... who compiled this ?

Is it working like this way ...when I first execute the code below
DBMS compiles when it encounter for the first time and then next time
DBMS does not compile . So, We call it precompiled.

java code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)



If I used Statement instead of PreparedStatement does that mean
everytime DBMS will compile the SQL query ?
 
L

Lew

gk said:
Please see this ..

http://java.sun.com/j2se/1.4.2/docs/api/java/sql/PreparedStatement.html

PreparedStatement : An object that represents a precompiled SQL
statement.

"precompiled SQL statement" ... who compiled this ?

There are a couple of layers of compilation, one at the JDBC layer
(potentially) and the other at the DBMS server.

Precompilation is not the only benefit of prepared statements.
Is it working like this way ...when I first execute the code below
DBMS compiles when it encounter for the first time and then next time
DBMS does not compile . So, We call it precompiled.

Roughly speaking, yes, although the full truth is somewhat more complicated.
java [sic] code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)



If I used Statement instead of PreparedStatement does that mean
everytime DBMS will compile the SQL query ?

Roughly speaking, yes, although the full truth is somewhat more complicated.
 
R

Robert Klemme

There are a couple of layers of compilation, one at the JDBC layer
(potentially) and the other at the DBMS server.

Precompilation is not the only benefit of prepared statements.


Roughly speaking, yes, although the full truth is somewhat more
complicated.

It is important to mention that for PS to work efficiently the statement
must be kept in user code. Invoking prepareStatement() with the same
string argument twice makes no guarantees about saving compilation in
the DB. To make the code efficient user must prepare the statement and
keep it around for recurring use.

That is, if you want to benefit from compilation savings - if it is only
for avoidance of SQL injection / proper conversion of arguments and
performance does not matter you can recreate PS over and over again-
java [sic] code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)



If I used Statement instead of PreparedStatement does that mean
everytime DBMS will compile the SQL query ?

Roughly speaking, yes, although the full truth is somewhat more
complicated.

Somehow that sentence sounds familiar. ;-)

Cheers

robert
 
A

Arne Vajhøj


In general you should use the latest documentation (1.6) unless
you specifically develop for an old version.
PreparedStatement : An object that represents a precompiled SQL
statement.

"precompiled SQL statement" ... who compiled this ?

Is it working like this way ...when I first execute the code below
DBMS compiles when it encounter for the first time and then next time
DBMS does not compile . So, We call it precompiled.

java code:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00)
pstmt.setInt(2, 110592)

If I used Statement instead of PreparedStatement does that mean
everytime DBMS will compile the SQL query ?

I believe that the actual implementation is database and/or
JDBC driver specific.

Some primitive databases and JDBC drivers will work like:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET
SALARY = ? WHERE ID = ?"); // store SQL in memory in pstmt object
pstmt.setBigDecimal(1, new BigDecimal("153833.00")); // replace value in
memory
pstmt.setInt(2, 110592); // replace value in memory
pstmt.executeUpdate(); // send SQL to database which compiles & execute
pstmt.setBigDecimal(1, new BigDecimal("153834.00")); // replace value in
memory
pstmt.setInt(2, 110593); // replace value in memory
pstmt.executeUpdate(); // send SQL to database which compiles & execute

Better databases and JDBC drivers will work like:

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET
SALARY = ? WHERE ID = ?"); // send SQL to database for compilation
pstmt.setBigDecimal(1, new BigDecimal("153833.00")); // send value to
database
pstmt.setInt(2, 110592); // send value to database
pstmt.executeUpdate(); // tell database to execute
pstmt.setBigDecimal(1, new BigDecimal("153834.00")); // send value to
database
pstmt.setInt(2, 110593); // send value to database
pstmt.executeUpdate(); // tell database to execute

The first just handles proper handling of input with
single quotes (incl. malicious SQL injection) and date
formats.

The second also does that but will typical also provide
a performance improvement, because the SQL is
reused in compiled form in the database tier and
less data is send over the wire.

You should practically always use PreparedStatement!

Arne
 
A

Arne Vajhøj

It is important to mention that for PS to work efficiently the statement
must be kept in user code. Invoking prepareStatement() with the same
string argument twice makes no guarantees about saving compilation in
the DB. To make the code efficient user must prepare the statement and
keep it around for recurring use.

That is, if you want to benefit from compilation savings - if it is only
for avoidance of SQL injection / proper conversion of arguments and
performance does not matter you can recreate PS over and over again-

Note that good database connection pools are able to reuse
real driver prepared statement even if the pool driver
prepared statement is not reused.

Arne
 
R

Robert Klemme

Note that good database connection pools are able to reuse
real driver prepared statement even if the pool driver
prepared statement is not reused.

Good point! I have to say I'm wary to use those features as long as
there is no guarantee that the environment of an application is
stable. If it has to run with a pool with and without PS caching you
need to to the caching yourself. Otherwise you might see dramatic
performance differences. If you know the app is only ever going to be
used in an environment relying on this feature is of course perfectly
OK.

Kind regards

robert
 
L

Lew

Robert Klemme said:
Good point!  I have to say I'm wary to use those features as long as

You're wary to use which features? PreparedStatement? Database
connection pooling?
there is no guarantee that the environment of an application is
stable.  If it has to run with a pool with and without PS caching you
need to to the caching yourself.  Otherwise you might see dramatic
performance differences.  If you know the app is only ever going to be
used in an environment relying on this feature is of course perfectly
OK.

If the environment is not stable, then performance variations are
normal and expected, and optimization is premature. This does not
militate against using PreparedStatement nor against connection
pools. It's beneficial to use both, and should be required to use the
former.

Unless you meant some other features, in which case I don't understand
your comment.
 
R

Robert Klemme

You're wary to use which features? PreparedStatement? Database
connection pooling?

I meant to say I am wary to rely on a pool caching prepared statements
if either the environment of the JDBC application is undefined or may
change. All I was trying to say is that it should not be taken for
granted that the overhead of Connection.prepareStatement() is always low
just because there are situations (the mentioned pools which cache PS)
where this is the case.
If the environment is not stable, then performance variations are
normal and expected, and optimization is premature. This does not
militate against using PreparedStatement nor against connection
pools. It's beneficial to use both, and should be required to use the
former.

One definitively should use PS - just not mindlessly recreating a PS for
the same SQL via the Connection. That decision should be taken
consciously and if it is not known what the source of the Connection
does then IMHO it's better to keep PS around for the time that they are
repeatedly used with the same Connection.
Unless you meant some other features, in which case I don't understand
your comment.

I was probably too unclear. Sorry for that.

Cheers

robert
 
L

Lew

Robert said:
One definitively should use PS - just not mindlessly recreating a PS for
the same SQL via the Connection.  That decision should be taken
consciously and if it is not known what the source of the Connection
does then IMHO it's better to keep PS around for the time that they are
repeatedly used with the same Connection.

I see your point and agree wholeheartedly.

I go a step further and suggest that one keep the PreparedStatement
around for use within the same use of a Connection regardless of the
promise you think the connection pool makes. From a logical
standpoint, an application acquires a new Connection each time; that
the Connection may be pooled and may be the same as one from an
earlier use is hidden from the application. Ergo, whether the
PreparedStatement obtained from the Connection is reused from an
earlier invocation is also hidden. Ergo, it is foolish to rely on
putative promises that depend on such reuse.

The point of connection pools is to let an application pretend that
it's getting a new Connection (and thus a virgin PreparedStatement)
each time even though under the hood the pooler is reusing them. You
can't simultaneously pretend that the Connection is new and rely on it
being reused.
 
R

Robert Klemme

I see your point and agree wholeheartedly.

I go a step further and suggest that one keep the PreparedStatement
around for use within the same use of a Connection regardless of the
promise you think the connection pool makes. From a logical
standpoint, an application acquires a new Connection each time; that
the Connection may be pooled and may be the same as one from an
earlier use is hidden from the application. Ergo, whether the
PreparedStatement obtained from the Connection is reused from an
earlier invocation is also hidden. Ergo, it is foolish to rely on
putative promises that depend on such reuse.

The point of connection pools is to let an application pretend that
it's getting a new Connection (and thus a virgin PreparedStatement)
each time even though under the hood the pooler is reusing them. You
can't simultaneously pretend that the Connection is new and rely on it
being reused.

That's a great way to express it - much better than my wariness.

Kind regards

robert
 
A

Arne Vajhøj

Good point! I have to say I'm wary to use those features as long as
there is no guarantee that the environment of an application is
stable. If it has to run with a pool with and without PS caching you
need to to the caching yourself. Otherwise you might see dramatic
performance differences. If you know the app is only ever going to be
used in an environment relying on this feature is of course perfectly
OK.

Of:

A)
- writing simple easy to read code
- tell the operations guys to setup a good connection pool to
get good performance
B)
- drop the app server connection pool
- embed a good connection pool with the app
C)
- write code that keeps connections and prepared
statements open for longer time

then I would prefer #A and #B over #C.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top