Tải bản đầy đủ (.pdf) (17 trang)

Streaming Data Types phần 2

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (70.08 KB, 17 trang )

getAsciiStream( ), getBinaryStream( ), and getCharacter-Stream( ); the
nonstreaming get methods are getBytes( ) and getString( ).
12.5.1 Inserting or Updating a LONG
Other than the use of the methods just mentioned, when inserting or updating a LONG, there are
limitations on the size of a String or byte array that you can update using the setString( )
or setBytes( ) methods. These limitations are listed in Table 11-3. When you exceed these
limits, you will get the following error message: "Data size bigger than max size for this type:
####." To work around these limitations, you need to use the streaming methods.
12.5.2 Selecting a LONG
To retrieve data in ASCII, use the ResultSet object's getAsciiStream( ) method. You can
use the getAsciiStream( ) method only if the underlying database uses the US7ASCII or
WE8ISO8859P1 character set. Otherwise, you can use the getCharacterStream( ) method,
which returns UCS-2-encoded characters (Unicode) regardless of the underlying database's
character set. Even if you get the data as a String, the JDBC driver will stream the data for you.
If you use the getBinaryStream( ) method, one of two possibilities exists. If you are using the
OCI driver, and its client character set is not set to US7ASCII or WE8ISO8859P1, then a call to
the getBinaryStream( ) method returns data in the UTF-8 character set. If you are using the
Thin driver, and the database's character set is not set to US7ASCII or WE8ISO8859P1, then a
call to the getBinaryStream( ) method also returns data in the UTF-8 character set.
Otherwise, you'll get the data in the US7ASCII character set.
As with the LONG RAW data type, you must call the getXXX( ) methods for each column
returned by the SELECT statement in the same order in which those columns are listed in the
SELECT statement. Also, when processing a streamed column, you must process the streamed
data before calling another getXXX( ) method. Once you move on to another getXXX( )
method, the streamed data is no longer accessible. In addition, you can prevent the JDBC driver
from streaming LONG data by using the OracleResultSet object's defineColumnType( )
method, setting the data type of a LONG column to Types.VARCHAR. This may be desirable if
there are a small number of characters in the data to be stored.
Now that you are an expert on using streaming data types, let's take a look at how to call stored
procedures in Chapter 13.
Chapter 13. Callable Statements


CallableStatement objects are used to call stored procedures. The stored procedures
themselves can be written using PL/SQL or Java. If they are written in Java, they must be
published to the RDBMS by creating a SQL call specification. You can see examples of this in
Chapter 5. Stored procedures exist to perform data-intensive operations that cannot be
accomplished using just SQL, and they perform these operations inside the database where
network performance is a moot issue.
For example, let's say you need to access five different tables in order to perform a complex
calculation and need to store the result in a sixth table. Let's further assume that the calculation is
complex enough that it cannot be performed using just SQL. If you perform the work on a client,
then the client will have to retrieve all the data necessary to perform the calculation and send the
result back to the database. If the number of rows that need to be retrieved by the client is large,
this network transfer of data could consume an inordinate amount of elapsed time. However, if
you perform the calculation as a stored procedure, the elapsed time of transmitting data across
the network will be eliminated, and the resulting calculation will be much quicker. This example
represents the type of situation in which stored procedures excel.
As with all good things, stored procedures are sometimes taken to an extreme and are
sometimes used as a panacea. For example, some developers eliminate SQL from their
application altogether and use only stored procedures. This is not a good use of Oracle stored
procedures, simply because selecting data from a table from your application is faster than calling
a stored procedure that selects data from a table and returns it to your application. When you go
through a stored procedure, you have two network round trips instead of one.
Enough with my soapbox speeches! Let's get on to some real meat. In this chapter, you'll learn
how to identify the parameters for, and formulate, stored procedure calls using both SQL92 and
Oracle syntax. You'll learn how to create a CallableStatement object to execute stored
procedures, how to set and retrieve parameter values, and how to actually execute a stored
procedure. Let's get started by looking at how to identify stored procedure names and parameter
types.
13.1 Understanding Stored Procedures
With Oracle, stored procedure actually refers collectively to standalone stored functions,
standalone procedures, packaged functions, and procedures. So when I use the term stored

procedure in this chapter, please understand that I am referring generally to any of these
procedure or function types.
To call a stored procedure, you need to know the procedure name and know about any
parameters that will be passed to the procedure. In the case of a function, you also need to know
the return type. One way to get this information is to query Oracle's data dictionary views for
stored procedure source code and look at the signature for the procedures you wish to use. The
next section shows you how to interpret Oracle's stored procedure signatures. Following that is a
section that shows you, among other things, how to query the data dictionary for procedure
signatures.
13.1.1 Stored Procedure Signatures
It's important to know the differences in the syntax used by stored procedures so you can code
your callable statements appropriately. Oracle stored procedures are created using three different
syntaxes, one for standalone functions, another for standalone procedures, and a third for
functions and procedures that are part of a package.
13.1.1.1 Standalone functions
The difference between a procedure and function is that a function returns a value, so it can be
used as an evaluated item in an expression. The syntax to create a stored function is:
CREATE [OR REPLACE] [user.]FUNCTION function_name
[(parameters)]
RETURN data_type {AS | IS}
function_body

parameters ::= parameter_declaration [,parameter_declaration...]

parameter_declaration ::= parameter_name [IN | OUT | IN OUT] data_type
which breaks down as:
user
The schema owner of the function.
function_name
The name of the function.

RETURN data_type
Specifies the SQL data type returned by the function.
parameter_name
The name of a parameter passed to the function. Zero or more parameters may be
passed to a function.
IN | OUT | IN OUT
Specifies the use of a parameter. An IN parameter can be read, but you cannot write to it.
An OUT parameter can be written to but not read. You can both read from and write to an
IN OUT parameter.
data_type
The SQL data type of the parameter.
For example, to create an errorless TO_NUMBER function for user SCOTT, log into Oracle with
SQL*Plus as SCOTT/TIGER and execute the following PL/SQL code:
create or replace function ToNumberFun (
aiv_varchar2 in varchar2 )
return number is
begin
return to_number( aiv_varchar2 );
exception
when OTHERS then
return null;
end ToNumberFun;
/
13.1.1.2 Standalone procedures
Use the following syntax to create a standalone stored procedure. A procedure does not return a
value. However, both functions and procedures can have OUT or IN OUT variables that return
values.
CREATE [OR REPLACE] [user.]PROCEDURE procedure_name
[(parameters)] {AS | IS}
procedure_body

parameters ::= parameter_declaration [,parameter_declaration...]

parameter_declaration ::= parameter name [IN | OUT | IN OUT] data_type
See Section 13.1.1.1 for an explanation of the syntax.
13.1.1.3 Packages
A package is a collection of related functions and procedures. It has a specification that defines
which functions, procedures, and variables are publicly accessible. It also has a body that
contains the functions and procedures defined in the specification and possibly also contains
private functions, private procedures, and private variable declarations. Packages are an
improvement over standalone functions and procedures, because the separation between the
specification and body reduces stored procedure dependency problems. The syntax for creating
a package specification is:
CREATE [OR REPLACE] PACKAGE package_name AS
package_specification
in which package_name is the name of the package. The following syntax is used to create a
package body:
CREATE [OR REPLACE] PACKAGE BODY package_name AS
package_body
Why is this explanation of stored procedure syntax important? Because you need to understand
the stored procedure syntax in order to know the name of a stored procedure (or function), which
data types you can pass to it, and which data type it returns.
13.1.2 Describing Signatures
If you want to invoke a stored procedure and double-check its name and the parameters you
must pass to it, you can take one of several approaches. If you have access to SQL*Plus, you
can use one of the following variations on the DESCRIBE command:
desc[ribe] [schema.]function_name
desc[ribe] [schema.]procedure_name
desc[ribe] [schema.]package_name
The following example shows the DESCRIBE command being used to display information about
the ToNumberFun function owned by the user Scott:

SQL> desc tonumberfun
FUNCTION tonumberfun RETURNS NUMBER
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
AIV_VARCHAR2 VARCHAR2 IN
The JDBC API defines a method, named DatabaseMetaData.getProcedureColumns( ),
you can invoke to get stored procedure signature data. In practice, however, the
getProcedureColumns( ) method is not all that useful. Oracle stored procedures can be
overloaded, and, using getProcedureColumns( ), you can't distinguish between the different
overloaded versions of the same stored procedure. So, for Oracle at least, the
getProcedureColumns( ) method is useless.
A third way to determine the signature for a standalone function, standalone procedure, or
package is to take a peek at the source code. The program named
DescribeStoredProcedures, shown in Example 13-1, does this. You pass in the name of a
stored procedure on the command line, then the program queries the SYS.DBA_SOURCE view
for the source code and displays that source code. If you don't have access to the DBA views,
you can change the program to use SYS.ALL_SOURCE.
Example 13-1. Describing a stored procedure
import java.io.*;
import java.sql.*;
import java.text.*;

public class DescribeStoredProcedures {
Connection conn;

public DescribeStoredProcedures( ) {
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver(
));
conn = DriverManager.getConnection(

"jdbc:oracle:thin:@dssw2k01:1521:orcl", "scott", "tiger");
}
catch (SQLException e) {
System.err.println(e.getMessage( ));
e.printStackTrace( );
}
}

public static void main(String[] args)
throws Exception, IOException {
String storedProcedureName = null;
String schemaName = null;
if (args.length > 0)
schemaName = args[0];
if (args.length > 1)
storedProcedureName = args[1];
new DescribeStoredProcedures( ).process(
schemaName, storedProcedureName);
}

public void process(
String schemaName,
String storedProcedureName)
throws SQLException {

int rows = 0;
ResultSet rslt = null;
Statement stmt = null;
String previous = "~";
String schemaPattern = "%";

String procedureNamePattern = "%";

try {
if (schemaName != null && !schemaName.equals(""))
schemaPattern = schemaName;
if (storedProcedureName != null &&
!storedProcedureName.equals(""))
procedureNamePattern = storedProcedureName;
stmt = conn.createStatement( );
rslt = stmt.executeQuery(
"select type||' '||owner||'.'||name, line, text " +
"from sys.dba_source " +
"where type = 'FUNCTION' " +
"and owner like '" + schemaPattern + "' " +
"and name like '" + procedureNamePattern + "' " +
"union all " +
"select type||' '||owner||'.'||name, line, text " +
"from sys.dba_source " +
"where type = 'PROCEDURE' " +
"and owner like '" + schemaPattern + "' " +
"and name like '" + procedureNamePattern + "' " +
"union all " +
"select type||' '||owner||'.'||name, line, text " +
"from sys.dba_source " +
"where type = 'PACKAGE' " +
"and owner like '" + schemaPattern + "' " +
"and name like '" + procedureNamePattern + "' " +
"union all " +
"select type||' '||owner||'.'||name, line, text " +
"from sys.dba_source " +

"where type = 'TYPE' " +
"and owner like '" + schemaPattern + "' " +
"and name like '" + procedureNamePattern + "' " +
"order by 1, 2");
while (rslt.next( )) {
rows++;
if (!rslt.getString(1).equals(previous)) {
if (!previous.equals("~"))
System.out.println("");
previous = rslt.getString(1);
}
System.out.print(rslt.getString(3));
}
if (!previous.equals("~"))
System.out.println("");
}
catch (SQLException e) {
System.err.println("SQL Error: " + e.getMessage( ));
}
finally {
if (rslt != null)
try { rslt.close( ); } catch (SQLException ignore) { }
if (stmt != null)
try { stmt.close( ); } catch (SQLException ignore) { }
}
}

protected void finalize( )
throws Throwable {
if (conn != null)

try { conn.close( ); } catch (SQLException ignore) { }
super.finalize( );
}
}
Here are the results of using DescribeStoredProcedures to describe the
scott.ToNumberFun function:
C:\>java DescribeStoredProcedures SCOTT TONUMBERFUN
function ToNumberFun (
aiv_varchar2 in varchar2 )
return number is
begin
return to_number( aiv_varchar2 );
exception
when OTHERS then
return null;
Of course, the best place to get information on stored procedure names and parameters is from
written documentation, but we all know that from time to time, written documentation is not
available. Consequently, the SQL*Plus DESCRIBE command and the
DescribeStoredProcedures program can be quite handy.
Once you have the signature for the stored procedure you wish to execute, there is a problem
that can arise: the username that will execute the stored procedure may not have the rights to do
so.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×