Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Chapter 16: Advanced Use of Functions and ppt
PREMIUM
Số trang
103
Kích thước
1.7 MB
Định dạng
PDF
Lượt xem
1318

Chapter 16: Advanced Use of Functions and ppt

Nội dung xem thử

Mô tả chi tiết

LPAD('o',ROUND(AVG(ReturnedDate-CheckOutDate)/2,0),'o')

AS Graph

from BOOKSHELF_CHECKOUT

group by Name

order by AVG(ReturnedDate-CheckOutDate);

Day

1 2 3 4 5 6 7

NAME DAYSOUT ....0....0....0....0....0....0....0

---------------- ------- -----------------------------------

DORAH TALBOT 13 ooooooo

EMILY TALBOT 14 ooooooo

JED HOPKINS 18 ooooooooo

GERHARDT KENTGEN 19 ooooooooo

PAT LAVAY 21 oooooooooo

FRED FULLER 24 oooooooooooo

ROLAND BRANDT 52 oooooooooooooooooooooooooo

7 rows selected.

This use of LPAD is similar to what was done in Chapter 13, where the cows and bulls

were shown in their family tree. Basically, a lowercase o is the column here, and it is padded

on the left with a number of additional lowercase o’s, to the maximum width determined by

ROUND(AVG(ReturnedDate-CheckOutDate)/2,0).

Notice that the scale of the column heading is in increments of two. A simple change to the

SQL will produce a classic graph rather than a bar chart. The literal column is changed from an

o to a lowercase x, and the padding on the left is done by spaces.

select Name,

AVG(ReturnedDate-CheckOutDate) DaysOut,

LPAD('x',ROUND(AVG(ReturnedDate-CheckOutDate)/2,0),' ')

AS Graph

from BOOKSHELF_CHECKOUT

group by Name

order by AVG(ReturnedDate-CheckOutDate);

Day

1 2 3 4 5 6 7

NAME DAYSOUT ....0....0....0....0....0....0....0

---------------- ------- -----------------------------------

DORAH TALBOT 13 x

EMILY TALBOT 14 x

JED HOPKINS 18 x

GERHARDT KENTGEN 19 x

PAT LAVAY 21 x

FRED FULLER 24 x

ROLAND BRANDT 52 x

7 rows selected.

Chapter 16: Advanced Use of Functions and Variables 299

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:299

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:21 PM

Color profile: Generic CMYK printer profile

Composite Default screen

300 Part II: SQL and SQL*Plus

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:300

Another way to graph the data is by its distribution rather than by person. First, a view is

created that puts each number of days out into its decile. Thus 13, 14, 18, and 19 become 10;

20 through 29 become 20; 30 through 39 become 30; and so on:

create or replace view DaysOutRange as

select ROUND((ReturnedDate-CheckOutDate),-1) Decile,

COUNT(*) Counter

from BOOKSHELF_CHECKOUT

group by ROUND((ReturnedDate-CheckOutDate),-1);

Next, a column heading is set up, similar to the previous heading although shorter and in

increments of one:

column Graph Heading 'Count| 1 1|....5....0....5'-

justify c

column Graph format a15

The next SQL determines the count of values that are represented in each decile.

select Decile, Counter,

LPAD('o',Counter,'o') AS Graph

from DAYSOUTRANGE;

Count

1 1

DECILE COUNTER ....5....0....5

---------- ---------- ---------------

10 8 oooooooo

20 5 ooooo

30 3 ooo

50 2 oo

60 1 o

If one of the dates were NULL, the group by output would include a NULL group, with a

count and display similar to those shown in this listing. If you want to customize how Oracle

handles books with NULL ReturnedDate values, you can use the NVL function to replace the

NULL value with one of your choosing (such as SysDate). For more complex data replacement

logic, you can use DECODE and CASE, as introduced later in this chapter and more fully

described in Chapter 17.

Using TRANSLATE

TRANSLATE converts characters in a string into different characters, based on a substitution plan

you give it, from if to then:

TRANSLATE(string,if,then)

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:22 PM

Color profile: Generic CMYK printer profile

Composite Default screen

Chapter 16: Advanced Use of Functions and Variables 301

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:301

In the following SQL, the letters in a sentence are replaced. Any time an uppercase T is

detected, it is replaced by an uppercase T. In effect, nothing changes. Any time an uppercase

vowel is detected, however, it is replaced by a lowercase version of the same vowel. Any

letter not in the TAEIOU string is left alone. When a letter is found in TAEIOU, its position is

checked in the TAEIOU string, and the letter there is substituted. Thus, the letter E, at position

3 in TAEIOU, is replaced by e, in position 3 of Taeiou:

select TRANSLATE('NOW VOWELS ARE UNDER ATTACK','TAEIOU','Taeiou')

from DUAL;

TRANSLATE('NOWVOWELSAREUNDE

---------------------------

NoW VoWeLS aRe uNDeR aTTaCK

Eliminating Characters

Extending this logic, what happens if the if string is TAEIOU and the then string is only T ?

Checking for the letter E (as in the word VOWELS) finds it in position 3 of TAEIOU. There is

no position 3 in the then string (which is just the letter T ), so the value in position 3 is nothing.

So E is replaced by nothing. This same process is applied to all of the vowels. They appear in

the if string, but not in the then string. As a result, they disappear, as shown here:

select TRANSLATE('NOW VOWELS ARE UNDER ATTACK','TAEIOU','T')

from DUAL;

TRANSLATE('NOWVOWE

------------------

NW VWLS R NDR TTCK

This feature of TRANSLATE, the ability to eliminate characters from a string, can prove very

useful in cleaning up data. Recall the magazine titles in Chapter 7:

select Title from MAGAZINE;

TITLE

-------------------------------------

THE BARBERS WHO SHAVE THEMSELVES.

"HUNTING THOREAU IN NEW HAMPSHIRE"

THE ETHNIC NEIGHBORHOOD

RELATIONAL DESIGN AND ENTHALPY

"INTERCONTINENTAL RELATIONS."

The method used in Chapter 7 to clean out the periods and double quotes was a nested

combination of LTRIM and RTRIM:

select LTRIM( RTRIM(Title,'."') ,'"') from MAGAZINE;

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:22 PM

Color profile: Generic CMYK printer profile

Composite Default screen

The same goal can be accomplished with a single use of TRANSLATE:

select TRANSLATE(Title,'T".','T') AS TITLE

from MAGAZINE;

TITLE

-------------------------------------

THE BARBERS WHO SHAVE THEMSELVES

HUNTING THOREAU IN NEW HAMPSHIRE

THE ETHNIC NEIGHBORHOOD

RELATIONAL DESIGN AND ENTHALPY

INTERCONTINENTAL RELATIONS

In the listing, you have to include one character in the then string—in this case, the letter T

translates to the letter T. All other characters in the if set are eliminated.

Complex Cut and Paste

The NAME table contains a list of names as you might receive them from a mailing list company

or another application. First name, last name, and initials are all in one column:

column Name format a25

select Name from NAME;

NAME

-------------------------

HORATIO NELSON

VALDO

MARIE DE MEDICIS

FLAVIUS JOSEPHUS

EDYTHE P. M. GAMMIERE

Suppose you want to cut and paste these names and put them into a table with FirstName

and LastName columns. How would you go about it? The technique you learned in Chapter 7

involved using INSTR to locate a space, and using the number it returns in a SUBSTR to clip

out the portion up to that space. Here’s an attempt to do just that for the first name:

select SUBSTR(Name,1,INSTR(Name,' '))

from NAME;

SUBSTR(NAME,1,INSTR(NAME,

-------------------------

HORATIO

MARIE

FLAVIUS

EDYTHE

302 Part II: SQL and SQL*Plus

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:302

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:22 PM

Color profile: Generic CMYK printer profile

Composite Default screen

Chapter 16: Advanced Use of Functions and Variables 303

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:303

VALDO has vanished! The problem is that these names are not as consistent as the authors’

names were in Chapter 7. One of these names (probably a magician) is only one name long, so

there is no space for the INSTR to find. When INSTR has an unsuccessful search, it returns a 0.

The SUBSTR of the name VALDO, starting at position 1 and going for 0 positions, is nothing, so

he disappears. This is solved with DECODE. In place of this:

INSTR(Name,' ')

you put the entire expression, like this:

DECODE(INSTR(Name,' '),0,99,INSTR(Name,' '))

DECODE’s format is this:

DECODE(value,if1,then1[,if2,then2,if3,then3]...,else)

In the preceding example, DECODE tests the value of INSTR(Name, ‘ ‘). If it is equal to 0,

DECODE substitutes 99; otherwise, it returns the default value, which is also INSTR(Name, ‘ ‘).

The choice of 99 as a substitute is arbitrary. It will create an effective SUBSTR function for

VALDO that looks like this:

SUBSTR('VALDO',1,99)

This works because SUBSTR will clip out text from the starting number, 1, to the ending

number or the end of the string, whichever comes first. With the DECODE function in place,

the first names are retrieved correctly:

select SUBSTR(Name,1,

DECODE(INSTR(Name,' '),0,99,INSTR(Name,' ')))

from NAME;

SUBSTR(NAME,1,DECODE(INST

-------------------------

HORATIO

VALDO

MARIE

FLAVIUS

EDYTHE

How about the last names? You could use INSTR again to search for a space, and use the

location of the space in the string, plus one (+1), as the starting point for SUBSTR. No ending

point is required for SUBSTR, because you want it to go to the end of the name. This is what

happens:

select SUBSTR(Name,INSTR(Name,' ')+1)

from NAME;

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:23 PM

Color profile: Generic CMYK printer profile

Composite Default screen

304 Part II: SQL and SQL*Plus

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:304

SUBSTR(NAME,INSTR(NAME,''

-------------------------

NELSON

VALDO

DE MEDICIS

JOSEPHUS

P. M. GAMMIERE

This didn’t quite work. One solution is to use three INSTR functions, looking successively

for the first, second, or third occurrence of a space in the name. Each of these INSTRs will return

either the location where it found a space or a 0 if it didn’t find any. In a name with only one

space, the second and third INSTRs will both return 0. The GREATEST function, therefore, will

pick the number returned by the INSTR that found the space furthest into the name:

select SUBSTR(Name,

GREATEST(INSTR(Name,' '),INSTR(Name,' ',1,2),

INSTR(Name,' ',1,3)) +1)

from NAME;

SUBSTR(NAME,GREATEST(INST

-------------------------

NELSON

VALDO

MEDICIS

JOSEPHUS

GAMMIERE

Except for the fact that you also got VALDO again, this worked. (GREATEST also could have

been used similarly in place of DECODE in the previous example.) There is a second and simpler

method:

select SUBSTR(Name,INSTR(Name,' ',-1)+1)

from NAME;

SUBSTR(NAME,INSTR(NAME,''

-------------------------

NELSON

VALDO

MEDICIS

JOSEPHUS

GAMMIERE

The -1 in the INSTR tells it to start its search in the final position and go backward, or right

to left, in the Name column. When it finds the space, INSTR returns its position, counting from

the left as usual. The -1 simply makes INSTR start searching from the end rather than from the

beginning. A -2 would make it start searching from the second position from the end, and so on.

The +1 in the SUBSTR command has the same purpose as in the previous example: Once the

space is found, SUBSTR has to move one position to the right to begin clipping out the Name. If

no space is found, the INSTR returns 0, and SUBSTR therefore starts with position 1. That’s why

VALDO made the list.

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:23 PM

Color profile: Generic CMYK printer profile

Composite Default screen

How do you get rid of VALDO? Add an ending position to the SUBSTR instead of its default

(which goes automatically all the way to the end). The ending position is found by using this:

DECODE(INSTR(Name,' '),0,0,LENGTH(Name))

which says, “Find the position of a space in the Name. If the position is 0, return 0; otherwise,

return the LENGTH of the Name.” For VALDO, the DECODE produces 0 as the ending position

for SUBSTR, so nothing is displayed. For any other name, because there is a space somewhere,

the LENGTH of the Name becomes the ending position for the SUBSTR, so the whole last name

is displayed.

This is similar to the DECODE used to extract the first name, except that the value 99 used

there has been replaced by LENGTH(Name), which will always work, whereas 99 would fail

for a name longer than 99 characters. This won’t matter here, but in other uses of DECODE and

SUBSTR, it could be important:

select SUBSTR(Name,

INSTR(Name,' ',-1)+1,

DECODE(INSTR(Name,' '), 0, 0, LENGTH(Name)))

from NAME;

SUBSTR(NAME,INSTR(NAME,''

-------------------------

NELSON

MEDICIS

JOSEPHUS

GAMMIERE

This DECODE also could have been replaced by a GREATEST:

select SUBSTR(Name,

INSTR(Name,' ',-1)+1,

GREATEST(INSTR(Name,' '),0))

from NAME;

A third method to accomplish the same end uses RTRIM. Remember that RTRIM eliminates

everything specified in its set from the right side of a string until it encounters any character not

in its set. The RTRIM here effectively erases all the letters on the right until it hits the first space

(just before the last name) or reaches the beginning of the string:

select

SUBSTR(Name,LENGTH(RTRIM(NAME,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

+1)

from NAME;

SUBSTR(NAME,LENGTH(RTRIM(

-------------------------

NELSON

Chapter 16: Advanced Use of Functions and Variables 305

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:305

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:24 PM

Color profile: Generic CMYK printer profile

Composite Default screen

MEDICIS

JOSEPHUS

GAMMIERE

LENGTH then measures the resulting string (with the last name erased). This tells you the

position of the space before the last name. Add 1 to this number, do a SUBSTR starting there,

and you’ll get just the last name. Let’s create a table with FirstName and LastName columns

(you’ll see complete details on creating tables in Chapter 18):

create table TWONAME(

FirstName VARCHAR2(25),

LastName VARCHAR2(25)

);

Table created.

Now, use an insert with a subquery to load the table data with the first and last names from

the NAME table:

insert into TWONAME (FirstName, LastName)

select

SUBSTR(Name,1,DECODE(INSTR(Name,' '),0,99,INSTR(Name,' '))),

SUBSTR(Name,LENGTH(RTRIM(NAME,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))+1)

from NAME;

Check the contents of the TWONAME table:

select * from TWONAME;

FIRSTNAME LASTNAME

------------------------- -------------------------

HORATIO NELSON

VALDO

MARIE MEDICIS

FLAVIUS JOSEPHUS

EDYTHE GAMMIERE

You can use similar techniques to extract the middle initial or initials, and apply these methods

elsewhere as well, such as to addresses, product descriptions, company names, and so on.

When moving data from an old system to a new one, reformatting is frequently necessary

and often difficult. The facilities exist in SQL, but they require some knowledge of how the

functions work and some thoughtfulness to avoid the kinds of difficulties shown in the examples

so far in this chapter.

306 Part II: SQL and SQL*Plus

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:306

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:24 PM

Color profile: Generic CMYK printer profile

Composite Default screen

Chapter 16: Advanced Use of Functions and Variables 307

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:307

Counting String Occurrences

Within Larger Strings

You can use a combination of the LENGTH and REPLACE functions to determine how many

times a string (such as ABC) occurs within a larger string (such as ABCDEFABC). The REPLACE

function replaces a character or characters in a string with zero or more characters. Thus,

REPLACE('ADAH', 'A', 'BLAH')

will evaluate the string ADAH. Everywhere an A is found, it will be replaced with the string

BLAH. Thus, the function shown in this example will return the string BLAHDBLAHH.

You can use the REPLACE function to eliminate characters from strings. For example, you

can replace the character string you’re searching for with NULL values. Thus,

REPLACE('GEORGE', 'GE', NULL)

returns a value of OR. The two separate occurrences of GE in GEORGE were each set to NULL.

You can use the REPLACE function to determine how many times a string (like GE) is found

in a larger string (like GEORGE). First, replace the string with NULL values:

select REPLACE('GEORGE', 'GE', NULL)

from DUAL;

The result of that query will be OR:

RE

--

OR

More importantly, the LENGTH of the result of that query will provide information about

how many times the string was found. The following query will tell you how long the resulting

string is:

select LENGTH(REPLACE('GEORGE', 'GE', NULL))

from DUAL;

LENGTH(REPLACE('GEORGE','GE',NULL))

-----------------------------------

2

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:24 PM

Color profile: Generic CMYK printer profile

Composite Default screen

Now you can tell how many times the string was found. If you subtract the length of the

shortened string from the original string and divide that difference by the length of the search

string, the result will be the number of times the search string was found:

select (LENGTH('GEORGE')

- LENGTH(REPLACE('GEORGE', 'GE', NULL)) )

/ LENGTH('GE') AS Counter

from DUAL;

COUNTER

----------

2

This example uses strings instead of character columns in order to be simpler to understand;

in real applications, you would replace the original string (GEORGE) with your column name.

The length of the string GEORGE is six characters. The length of GEORGE after GE is replaced

with NULL is two characters. Therefore, the difference in the lengths of the original and

shortened strings is four characters. Dividing four characters by the length of the search string

(two characters) tells you that the string was found twice.

The only problem with this method occurs when the search string is zero characters in length

(since you cannot divide by zero). Searching for a zero-length string may indicate a problem with

the application logic that initiated the search.

Additional Facts About Variables

The command accept forces SQLPLUS to define the variable as equal to the entered value,

and it can do this with a text message, with control over the datatype entered, and even with

the response blanked out from viewing (such as for passwords; see the entry for accept in the

Alphabetical Reference).

You can pass arguments to a start file when it is started by embedding numbered variables

in the select statements (rather than variables with names).

To select all of the checkout records between one date and another, the select statement

might look like this:

select * from BOOKSHELF_CHECKOUT

where CheckOutDate BETWEEN '&1' AND '&2';

That query can be saved as a file (such as checkout.sql) and started from within SQLPLUS:

start checkout.sql 01-JAN-02 31-JAN-02

The start file checkout.sql would begin, with 01-JAN-02 substituted for &1, and 31-JAN-02

substituted for &2. As with other variables, character and DATE datatypes must be enclosed

in single quotation marks in the SQL statement. One limitation of this is that each argument

following the word start must be a single word without spaces.

Variable substitutions are not restricted to the SQL statement. The start file also may use

variables for such things as SQLPLUS commands.

308 Part II: SQL and SQL*Plus

ORACLE Series TIGHT / Oracle9i: The Complete Reference / Loney, Koch / 222521-1 / Chapter 16

Blind Folio 16:308

P:\010Comp\Oracle8\521-1\CD\Ventura\book.vp

Friday, July 19, 2002 4:12:25 PM

Color profile: Generic CMYK printer profile

Composite Default screen

Tải ngay đi em, còn do dự, trời tối mất!