SELECT decompose‘Châteaux’ AS decompose_str FROM dual Table 8.109 lists the results: Table 8.109 Decompose Results DECOMPOSE_STR Châteaux Translate The translate function translates stri
Trang 1Table 8.106 Simple Conversion Functions
Asciistr Returns the ASCII string Non-ASCII characters are
converted to their Unicode (UTF-16) binary code value Chartorowid Changes a string to a row id
Compose Returns a fully normalized Unicode string
Hextoraw Converts a hexadecimal number to a raw value
Rawtohex Converts a raw value to a hexadecimal number
Rowidtochar Converts a row id to a string
To_char Converts argument to a string
To_clob Converts argument to a CLOB
To_date Converts argument to a date
To_dsinterval Converts argument to a day-second interval
To_lob Converts argument to a LOB
To_multi_byte Converts a single character to a multibyte character To_nchar Identical to to_char, except that it converts to the
national character set
To_nclob Converts to the national character set
To_number Converts string to number Generally not used,
because Oracle automatically performs the conversion To_singlebyte Converts a multibyte character to single byte if possible To_yminterval Converts argument to a year-month interval
When used with dates, the to_char function takes the same format as that described
in the “Date Formatting” section When the to_char function is passed a number, it must decide how to appropriately output the string It does this by using a format mask similar to the date format mask you learned about earlier The most important element is the number 9 It represents a significant digit, and the number of 9’s repre-sents the number of significant digits that you want displayed Table 8.107 lists the number-format elements
Trang 2Table 8.107 Number-Format Elements
A significant digit
A padding zero
Usually appears on the left
$ Places a dollar sign in the output
B Zero values are displayed as blanks
MI Negative sign for negative values
S Forces the sign of the number to be displayed
PR Places negative values to be displayed in angle
brackets
C The International Organization for Standardization
(ISO) currency indicator
Convert
The convert function converts one character set to another If a character doesn’t exist
in the destination character set, a replacement character appears
SELECT CONVERT(‘Ä Ê Í Õ Ø A B C D E ‘, ‘US7ASCII’,
‘WE8ISO8859P1’) AS convert_str
FROM DUAL
Oracle SQL 221
Trang 3Table 8.108 lists the results.
Table 8.108 Convert Results
CONVERT_STR
A E I ? ? A B C D E ?
Decompose
The decompose function returns a Unicode string after decomposition
SELECT decompose(‘Châteaux’) AS decompose_str FROM dual
Table 8.109 lists the results:
Table 8.109 Decompose Results
DECOMPOSE_STR
Châteaux
Translate
The translate function translates strings to either the database character set or the national character set
SELECT translate(‘text’ USING char_cs) AS str FROM dual
Table 8.110 lists the results
Table 8.110 Translate Results
STR
text
Unistr
The unistr function returns a string in the database Unicode character set
SELECT UNISTR(‘\00D6’) AS str FROM dual
Trang 4Table 8.111 lists the results.
Table 8.111 Unistr Results
STR
Ö
Miscellaneous Functions
The remaining functions don’t fit easily into the other categories The most important functions to the XSQL developer are decode, which allows you to write conditional logic into your SQL functions, and nvl, which allows you to substitute a value when NULL is encountered
Table 8.112 lists the functions
Table 8.112 Miscelleneous Functions
Bfilename Returns a bfilename based on a specified directory
Coalesce Returns the first nonnull expression in list of
arguments, which are expressions
Decode Compares an expression to any number of search
values that are mated to results The result is returned for the first search value to match If none match, a default value will be returned
Dump Returns a dump of internal information for the given
expression
Empty_blob Returns an empty BLOB
Empty_clob Returns an empty CLOB
Nls_charset_decl_len Returns the declaration width of an NCHAR column
Nls_charset_id Returns a character set id number for a character
name
Nls_charset_name Returns a character set name for a character set id
Nullif Returns null if two expressions are equal, the first
expression otherwise
Nvl If an argument is null, replace it with the given value
(continues)
Oracle SQL 223
Trang 5Table 8.112 Miscelleneous Functions (Continued)
Nvl2 If the first expression isn’t null, return the second If
the first expression is null, return the third
Sys_guid Returns a system global unique identifier
Uid Returns the user id of the user who logged on
User Returns the user name of the user who logged on Vsize Returns the number of bytes in the internal
representation of the given expression
Moving On
In the previous chapters, you saw examples of some SQL in the code This chapter helped to fill out your understanding and showed you the ins and outs of SQL The next three chapters delve more deeply into the Oracle database technologies The tech-nologies described are by no means an inclusive representation of the entire Oracle database; rather, they are the technologies that you’ll find most useful in conjunction with XSQL
Trang 6C H A P T E R
9
PL/SQL stands for the procedural language extensions to SQL It gives you a new level of
power when working with the database Instead of being limited to the functions pro-vided by SQL, you can write your own You can also use all of the basics of procedural programming: loops, conditional statements, variables, and encapsulation
The PL/SQL code that you will be creating here is stored in the database Unlike code that executes at the client, server-side PL/SQL doesn’t incur the costs of network roundtrips Calls to PL/SQL can be integrated closely with SQL Likewise, PL/SQL can be used from XSQL and can be a valuable tool for you as you develop your XSQL applications This section outlines how to create PL/SQL code and the different options that are available
Hello, PL/SQL!
Your first step is to create a simple PL/SQL function and execute it from an XSQL page Your function will simply return the string “Hello, PL/SQL!” when called As with all PL/SQL code, you should create it in its own file and then load the file using SQL*PLUS By doing it this way, if you need to change the code later, it will be easy to
do so
PL/SQL
Trang 7T I P If you get a message that you have received compilation errors, you can use the SHOW ERRORS command from SQL*PLUS to see what those errors are.
For this example, you’ll create a package A package is a set of functions, parameters, and variables The definition looks a bit like a class, but PL/SQL isn’t an object-oriented language Rather, the PL/SQL package is just an encapsulation mechanism For this example, our package contains just one sub-routine Your subroutines can be stand-alone, but your code will be better organized and more reusable if you always use packages
CREATE OR REPLACE PACKAGE hello_pkg AS
FUNCTION hello_plsql (param NUMBER) RETURN VARCHAR2;
END hello_pkg;
Your next step is to create the body of your package This includes the actual code of your hello_plsql As is befitting a first try, our code is simple It takes the param, assumes that it is the empno for a row in the emp table, looks up the salary, and appends
it to the string “hello pl/sql:.” If the parameter passed doesn’t match an empno
in the database, then the string “invalid param” is returned
CREATE OR REPLACE PACKAGE BODY hello_pkg AS package body header FUNCTION hello_plsql (param NUMBER) function header
RETURN VARCHAR2 IS
hello_str VARCHAR2(20);
sal_val NUMBER(7,2); declaration block BEGIN
hello_str:=’hello pl/sql ‘; set the string
SELECT sal INTO sal_val SELECT statement FROM emp INTO is used to set WHERE param=empno; the sal_val variable
IF sal_val=NULL THEN conditional statement sal_val:=-1;
END IF;
hello_str:=hello_str || sal_val; combining the strings RETURN hello_str;
EXCEPTION if the SELECT statement WHEN NO_DATA_FOUND THEN returned nothing, RETURN ‘invalid param’; this code executes END;
END hello_pkg
With this package successfully compiled, you can invoke the function just like you invoked a lot of the SQL functions Just select it as a pseudocolumn from the dual table Just pass to it an employee ID that you know is valid, such as 7900
SELECT hello_pkg.hello_plsql(7900) AS hello_plsql FROM dual
You should get the following result:
hello pl/sql 950
Trang 8Of course, you aren’t limited to only using this function with the dual table You can use this function anywhere that functions are permitted In this example, the function
is called as an element in the SELECT statement of the emp table
SELECT hello_pkg.hello_plsql(empno) AS hello_plsql FROM emp WHERE
deptno=10
In this case, the function is called for each row in emp where deptno is equal to ten The result of this statement should look like this:
hello pl/sql 2450
hello pl/sql 5000
hello pl/sql 1300
Your final step is to use this example in an XSQL page Your XML page will look like this:
<?xml version=”1.0”?>
<page connection=”demo” xmlns:xsql=”urn:oracle-xsql”>
<xsql:query>
SELECT hello_pkg.hello_plsql(empno) AS hello_plsql
FROM emp
WHERE deptno=10
</xsql:query>
</page>
This should produce output as seen in Figure 9.1
Figure 9.1 XSQL and the hello_plsql function.
PL/SQL 227
Trang 9The preceding example gave you a taste of PL/SQL code Now you will step back and look at how PL/SQL is structured Because you created a named function inside of a package in the first example, you have already seen most of the structural components that PL/SQL code can have In these pages, you’ll learn the names for the parts that you have already learned and see what the other pieces are
PL/SQL code is defined as blocks The individual statements (such as control state-ments, SQL statestate-ments, variable declarations, and variable assignments) are included
in these blocks
Block header. This block formally names and contains another block In our hello_plsqlfunction, the line beginning with FUNCTION hello_plsql and ending in a semicolon was a block header It contained a declaration block and
an execution block Likewise, the package declaration is another block header that contains all of the blocks in our sample code Block headers are optional If there is a block header, the code that it contains is a named block; in the absence
of a block header, the code is an anonymous block Named blocks are generally preferable because they are easier to reuse
Declaration section. The declaration section declares the variables that you want
to use It is also optional—there are many times that you don’t need to declare variables Our hello_plsql function had a declaration block consisting of one line: sal_val NUMBER(7,2); Any variable used in the execution section must be declared in the declaration section
Execution section. The execution section is the meat of your code All of the code between the BEGIN statement and the EXCEPTION statement belongs to the exe-cution block
Exception section. The exception block handles errors that are encountered in the execution block In the case of hello_plsql, it handles the case where the SELECTstatement returns no rows
These blocks represent the core basics of PL/SQL code In addition to these blocks, you can also have a package specification, which was the first statement that you exe-cuted It declares the package to the world and declares what is in it Now that you know the basic parts of PL/SQL, you can start examining each part in turn
Declaring Variables
As described earlier, all of your variables must be declared in the declaration section (This differs from C++ and Java, in which you can declare variables anywhere in your code.) There are many types of variables that can be declared Many are simple scalar data types that are identical to what you have seen in SQL You’ll learn those first You can also have record variables that are data structures containing several different
Trang 10variables of possibly different types As you would expect from any decent program-ming language, PL/SQL has arrays Perhaps most important, PL/SQL has cursors A cursor contains the results of a SQL SELECT statement By using a cursor, your SQL code can easily iterate over data in your database
Scalar Variable Declarations
Scalar variable declarations take the following form:
name [CONSTANT] type [NOT NULL] [:=|DEFAULT initial_value]
Using the CONSTANT keyword declares that the variable is a constant—the value can’t be changed NOT NULL declares that the variable can never be set to a NULL value Both of these keywords require that the initial value be set—either the assignment operator or the DEFAULT keyword can be used Of course, you don’t have to declare a variable to be NOT NULL or CONSTANT if you simply want to set an initial value, and you aren’t required to set an initial value at all You’ve already seen the easiest way to declare a variable in the hello_plsql example In that code, you declared a scalar variable of type NUMBER(7,2) with the following line:
sal_val NUMBER(7,2);
This is the simplest scalar variable declaration You give the variable name followed
by the type Perhaps more useful, though, is referencing an existing database column:
sal_val emp.empno%TYPE;
This declaration tells PL/SQL that you want the variable to take the type of the empnocolumn in the emp table If you know that you are going to be using the variable
to set data from a specific column (as you did in our example), you should do it this way First, if the underlying table changes, you don’t have to modify your code Sec-ond, it becomes obvious to anyone reading your code that the variable is related to that particular column
The following lines show examples of all of the remaining permutations of declar-ing scalar variables:
dummy_1 emp.empno%TYPE :=7900;
dummy_2 NUMBER(7,2) :=7900;
dummy_3 emp.empno%TYPE NOT NULL :=7900;
dummy_4 NUMBER(7,2) NOT NULL :=7900;
dummy_5 CONSTANT emp.empno%TYPE :=7900;
dummy_6 CONSTANT NUMBER(7,2) :=7900;
Though you should declare variables based on a database column whenever practi-cal, there are many cases in which this isn’t done The following tables list all of the data types that you can use when you are explicitly declaring the types of your variables
PL/SQL 229
Trang 11First, look at the numeric data types in Table 9.1 Many equate with each other This
is for compatibility with other vendors’ systems You shouldn’t skip around between equivalent data types—simply pick one that you like and stick to it This will make your code easier to read
Table 9.1 PL/SQL Numeric Data Types
DOUBLE PRECISION NUMBER Equivalent to NUMBER
digits with no fractional part (nothing to the right
of the decimal point)
restricted to nonnegative values but can be NULL
restricted to nonnegative and can’t be NULL
NUMBERdata type
between -2,147,483,647 and 2,147,483,647 Faster than NUMBER
restricted to nonnegative values but can be NULL
restricted to nonnegative values and can’t be NULL
SIGNTYPE BINARY INTEGER Restricted to the values
-1, 0, and 1