1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Teach Yourself PL/SQL in 21 Days- P11 docx

50 313 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Generating Dynamic SQL
Trường học Vietnam National University, Hanoi
Chuyên ngành Computer Science
Thể loại Sách tự học PL/SQL trong 21 ngày
Thành phố Hà Nội
Định dạng
Số trang 50
Dung lượng 2,7 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Declare a string of type VARCHAR2to act as a buffer for reading in the file one line 5.. The Syntax for the FCLOSEProcedure PROCEDURE FCLOSEfile IN OUT file_type; Thefileparameter is the

Trang 1

Of those three steps, only the first step represents a difference from what you would do

to process a static SELECTstatement by using PL/SQL

The Syntax for the OPEN FORStatement

OPEN cursor FOR string [USING bind[, bind] ];

In this syntax the parameters are as follows:

• cursoris the cursor that you want to open This is actually a pointer to a cursor,and must be a REF CURSORvariable

• stringis a variable or literal that contains the SQL statement you want to execute

• bindis a bind variable You use these to pass parameters to the dynamic SQL ment The parameter markers are numbered, and must be :1,:2, and so on Thefirst bind variable becomes the value :1, the second bind variable becomes thevalue :2, and so forth

state-The cursor that you declare and use with the OPEN FORstatements must be a REF SOR You can declare a REF CURSORlike this:

CUR-TYPE ref_cursor_type IS REF CURSOR;

your_cursor ref_cursor_type;

Listing 16.8 shows OPEN FORbeing used to open a cursor on a dynamic SQL ment The rows returned by that statement are then fetched into a PL/SQL record, andfrom there they are displayed by using DBMS_OUTPUT

state-L ISTING 16.8 Executing a SELECT by Using Native Dynamic SQL

1: DECLARE 2: TYPE your_cursor_type IS REF CURSOR;

10:

11: Note, could also use:

12: dyn_rec yourtable%ROWTYPE;

13: 14: dyn_rec dyn_record;

Trang 2

16: dynamic_select_stmt VARCHAR2(100);

17: BEGIN 18: Generate the dynamic SELECT statement.

24: Open a cursor on the dynamic statement.

25: OPEN your_cursor FOR dynamic_select_stmt;

26:

27: Loop through and display all the data.

28: LOOP 29: Fetch the next row, exit the loop when 30: no more data is left.

31: FETCH your_cursor 32: INTO dyn_rec;

33: EXIT WHEN your_cursor%NOTFOUND;

TheREF CURSERvariable used with the OPENstatement is declared in lines 2–3.Lines 18–20 build on the initial SELECTstatement, and the next two lines (21–22)add an ORDER BYclause The cursor is opened in line 25, through the use of the

OPEN FORstatement Note that OPEN FORreferences the VARCHAR2variable containingtheSELECTstatement From here on out, it’s just normal everyday PL/SQL cursor pro-cessing The FETCHin lines 31–32 fetches the data from the cursor into a record Youcould also fetch the data into a list of variables The DBMS_OUTPUTcall in line 36–37allow SQL*Plus to display the data, and the CLOSEstatement in line 41 closes the cursorafter all the data has been processed

L ISTING 16.8 continued

OUTPUT

A NALYSIS

Trang 3

Executing PL/SQL Blocks

You can execute PL/SQL blocks by using native dynamic SQL through the use of theEXECUTE IMMEDIATEstatement Listing 16.9 shows the native dynamic SQL version ofListing 16.4

L ISTING 16.9 Executing a PL/SQL Block Using Native Dynamic SQL

1: DECLARE 2: block_to_execute VARCHAR2(200) :=

3: ‘BEGIN 4: SELECT YourRow,YourDesc 5: INTO :1, :2 FROM YourTable 6: WHERE YourRow = 2;

to execute the block The crucial thing to note here is that the bind variables listed in theUSINGclause both have the keyword OUTin front of them This allows them to receivevalues back from the PL/SQL block So the PL/SQL block issues a SELECT INTOstate-ment that places values into these variables, and because they are OUTbind variables,those values are returned to you

INPUT

A NALYSIS

This code fails if there are two rows in YOURTABLE with a value of 2 for the

YOURROW column If you ran Listing 16.7 more than once, that might be the case.

Caution

Trang 4

Today’s lesson covers Oracle’sDBMS_SQLpackage, as well as the new native dynamicSQL features included with Oracle8i Both let you dynamically build and execute SQLstatements from within PL/SQL DBMS_SQLis the way to go if your code must run onreleases of Oracle prior to the 8i release Otherwise, you should use native dynamic SQL

if you can You’ll find it much easier to deal with, and the resulting code will be moreeasily understood

With DBMS_SQL, you have to open a cursor for each statement, define bind variables, fetchrows returned by queries, and get each column one at a time Quite a lot of code is need-

ed to do all that, and that code is rather tedious to write Native Dynamic SQL simplifiesthings Using Native Dynamic SQL, as with DBMS_SQL, you open a cursor for a dynami-cally generated SQL statement However, unlike with DBMS_SQL, you can then treat thatcursor as an ordinary PL/SQL cursor Fetching the data then becomes a very easy task

Q&A

Q Now that native dynamic SQL has arrived, is there any reason I would ever useDBMS_SQL?

A There probably are some reasons, but there sure aren’t many One thing that

DBMS_SQLcan handle that native dynamic SQL can’t, at least not easily, is the tion where you know absolutely nothing about the tables and columns that you will

situa-be querying DBMS_SQLallows you to issue a query, and then dynamically discoverhow many columns the query returns, as well as what the datatypes are That’s afairly advanced use, but if you need to be able to do it, then you need to useDBMS_SQL

Q What three types of statements can be executed dynamically?

A Using dynamic SQL, you can execute non-query DDL and DML statements, SQL

queries, and anonymous PL/SQL blocks

Q Should dynamically executed queries be written with trailing semicolons?

A No! This is a very common mistake to make Do not include a trailing semicolon

with any dynamic SQL statement The reason is that strictly speaking, the colon is not part of the SQL syntax You need it when you write a static SQL state-ment, because Oracle needs to know where the SQL statement ends However,when you are writing dynamic SQL, you are only working with one statement at atime, so a terminator is not needed

Trang 5

A You need to open a cursor, parse the statements to be executed, bind any variables

that are necessary, define columns if you are executing a SELECTstatement, executethe query, retrieve the data (if there is any) into some PL/SQL variables, and closethe cursor

2 What is meant by the term dynamic SQL?

3 What is Oracle’s term for the new version of dynamic SQL?

4 When using native dynamic SQL, what new form of the OPENstatement is used toopen a cursor on a dynamic SQL statement?

Exercise

Write a stored procedure to take a username as an argument, and create a version ofmytablein that user’s schema

Trang 7

D AY 17

Writing to Files and the Display

by Timothy Atwood and Jonathan Gennick

The PL/SQL language itself does not have any mechanism for performingeither file or screen output However, Oracle supplies a number of built-inpackages that allow you to perform I/O, and that can be called from PL/SQL.Today’s lesson talks about the following:

• TheDBMS_OUTPUTpackage

• TheUTL_FILEpackage

• TheTEXT_IOpackageYou’ve already seen DBMS_OUTPUTused throughout this book as a way to dis-play output on the screen, using SQL*Plus It has some other capabilities, too,which you’ll learn about today The UTL_FILEandTEXT_IOpackages allow you

to read and write text files UTL_FILEis a server-side built-in package thatallows you to read and write files on the database server TEXT_IOis an OracleDeveloper package that allows you to do file input/output (I/O) on the client

Trang 8

Exploring the DBMS_OUTPUT Package

Looking at many of the examples in this book might lead you to believe thatDBMS_OUTPUT’s only function is to allow you to display PL/SQL output using SQL*Plus.That’s only part of the story, though DBMS_OUTPUTis actually designed to let you writeoutput to a buffer in memory, and then read that output back again Figure 17.1 illustratesthis, and also shows how SQL*Plus fits into the picture

F IGURE 17.1

DBMS_OUTPUTallows you to read and write data to and from a buffer in memory.

by making calls to GET_LINE

The usefulness of DBMS_OUTPUTbecomes apparent when you realize that the procedurethat reads data from the buffer does not have to be the same procedure that wrote it there

in the first place Any procedure can read the data When you issue the command SET SERVEROUTPUT ONin SQL*Plus, you are really telling SQL*Plus to check the buffer fordata after each statement executes, fetch any data that’s found, and display it for you tosee In its most generic sense,DBMS_OUTPUTcan be used to communicate data betweenany two PL/SQL procedures

DBMS_OUTPUT allows you to communicate between two program units that are part of the same session To communicate across sessions, you need to use the DBMS_PIPE package You’ll learn about that on Day 19, “Alerting and Communicating with Other Procedures: The DBMS_ALERT and DBMS_PIPE

Packages.”

Note

Enabling the DBMS_OUTPUT Package

Before you can use DBMS_OUTPUT, you need to call the initialization procedure DBMS_OUTPUT.ENABLE SQL*Plus does this for you automatically whenever you issue aSET SERVEROUTPUT ONcommand However, you might want to do it yourself The mainreason that you might want to call DBMS_OUTPUT.ENABLEyourself is to allocate a buffer

Trang 9

larger than the default of 20,000 characters Another reason to call DBMS_OUTPUT.ENABLEyourself would be if SQL*Plus isn’t the destination for your messages

The Syntax for the DBMS_OUTPUT.ENABLEProcedure

DBMS_OUTPUT.ENABLE (buffer_size IN INTEGER DEFAULT 20000);

Thebuffer_sizeparameter controls the size of the buffer, and can be any value between2,000 and 1,000,000 The default is 20,000

The following PL/SQL block shows a call to enable the DBMS_OUTPUTpackage:

BEGIN DBMS_OUTPUT.ENABLE (1000000);

END;

If you are using DBMS_OUTPUTto send a lot of data to SQL*Plus, keep in mind thatSQL*Plus can’t begin reading until all the data is sent Therefore, your buffer must belarge enough to contain all the output Also bear in mind that SQL*Plus release 8.0 andabove allows you to specify the buffer size as an argument to the SET SERVEROUTPUT ONcommand For example, the following command also enables DBMS_OUTPUT, and with abuffer size of 1,000,000 bytes:

SET SERVEROUTPUT ON SIZE 1000000After you enable the package, you can use it to write data to the buffer, and to read itback again

Disabling the DBMS_OUTPUT Package

When you’re done using DBMS_OUPUT, you can disable the package by making a call toDBMS_OUTPUT.DISABLE This has the effect of purging the buffer of any remaining infor-mation

The Syntax for the DBMS_OUTPUT.DISABLEProcedure

DBMS_OUTPUT.DISABLE;

There are no parameters to the DISABLEprocedure The following PL/SQL block showshow it is called:

BEGIN DBMS_OUTPUT.DISABLE;

Trang 10

Writing Data to the Buffer

You write data to the DBMS_OUTPUTbuffer by using a combination of the PUT_LINE,PUT,andNEW_LINEprocedures.PUT_LINEwrites a line of text, followed by a newline charac-ter PUTwrites text, but doesn’t follow that text with a newline The NEW_LINEprocedurewrites one newline character

The Syntax for the DBMS_OUTPUT.PUT_LINE, DBMS_OUTPUT.PUT, and

DBMS_OUTPUT.NEW_LINEProcedures

DBMS_OUTPUT.PUT_LINE (item IN NUMBER);

DBMS_OUTPUT.PUT_LINE (item IN VARCHAR2);

DBMS_OUTPUT.PUT_LINE (item IN DATE);

DBMS_OUTPUT.PUT (item IN NUMBER);

DBMS_OUTPUT.PUT (item IN VARCHAR2);

DBMS_OUTPUT.PUT (item IN DATE);

over-The following example, in Listing 17.1, shows DBMS_OUTPUTbeing enabled, and somedata being written to the buffer SQL*Plus has been used to execute the block and cap-ture the output

L ISTING 17.1 Using DBMS_OUTPUT to Place Data in the Buffer

1: SET SERVEROUTPUT ON 2:

3: BEGIN 4: We only need a small buffer for this example.

Trang 11

This PL/SQL block writes one line into the buffer by using the PUT_LINEdure (line 5) It then writes three more lines using a combination of the PUTandNEW_LINEprocedures (lines 6–11) Because SERVEROUTPUThad been turned on,

proce-SQL*Plus reads the data from the buffer and displays it onscreen

ThePUTandPUT_LINEprocedures only handle lines up to 255 characters long If youattempt to write a line longer than that, you get an error You also get an error if youattempt to write more data into the buffer than it will hold

Reading Data from the Buffer

Two procedures,GET_LINEandGET_LINES, allow you to read from the buffer GET_LINEallows you to read one line at a time, and GET_LINESallows you to read several lines into

In this syntax the parameters are as follows:

• lineis the line retrieved by GET_LINE

• statusindicates whether a line was retrieved A status of 1means that the lineparameter contains a line retrieved from the buffer A status of 0means that thebuffer was empty[md]that is, nothing was retrieved

• linesis a table of VARCHAR2(255) You can declare this table by using the typeDBMS_OUTPUT.CHARARR See Listing 17.2 for an example

• numlinesis both an input and an output When calling GET_LINES, you should setthis to the number of lines that you want to retrieve GET_LINESreplaces that valuewith the number of lines that were actually retrieved

Trang 12

The example in Listing 17.2 is an extension of Listing 17.1 It shows GET_LINEbeingused to retrieve the three names from the buffer It also demonstrates that the buffer con-tents are maintained across PL/SQL blocks.

This listing should be executed from SQL*Plus.

Note

L ISTING 17.2 Using GET_LINE to Retrieve Data From the Buffer

1: SET SERVEROUTPUT OFF 2:

3: BEGIN 4: We only need a small buffer for this example.

17: PL/SQL procedure successfully completed.

18:

19:

20: SET SERVEROUTPUT ON 21: DECLARE

39: DBMS_OUTPUT.PUT_LINE(name1 || ‘ and ‘ ||

40: name2 || ‘ and ‘ || name3);

I NPUT /

O UTPUT

Trang 13

The first PL/SQL block (lines 3–14) writes three names into the buffer, one name

to a line Because this example is executed from SQL*Plus, the SERVEROUTPUTsetting is turned off (line 1) to prevent SQL*Plus from reading and displaying the names

Instead, the names remain in the buffer, where they can be accessed by the second block

The second PL/SQL block (lines 21–41) reads the first line and throws it away (line28–29) Then it reads each of the three names (lines 32–34) Finally, it concatenatesthose three names together in one line, and writes that line back out to the buffer (lines36–40) Because the SERVEROUTPUTsetting has been turned on for the second block,SQL*Plus reads the results and displays them onscreen

L ISTING 17.3 Using GET_LINES to Retrieve Three Lines from the Buffer with One Procedure Call

1: SET SERVEROUTPUT OFF 2:

3: BEGIN 4: We only need a small buffer for this example.

Trang 14

13: DBMS_OUTPUT.NEW_LINE;

14: END;

15: / 16:

17: PL/SQL procedure successfully completed.

18:

19:

20: SET SERVEROUTPUT ON 21: DECLARE

L ISTING 17.3 continued

A NALYSIS

Trang 15

GET_LINESoccurs in lines 32–34 The lines_to_getparameter contains the value 3,tellingGET_LINESto return all three names The loop in line 40–43 then uses the valuethatGET_LINESpasses back to iterate through the array the proper number of times IfGET_LINESreturned more than three lines, or fewer than three lines, the value oflines_to_getwould be set appropriately, and the loop would concatenate all the linestogether

Exceptions Raised from the DBMS_OUTPUT Package

There are two exceptions you have to worry about when using the DBMS_OUTPUTpackage

These are described in Table 17.1, along with the actions required to fix the problems

T ABLE 17.1 Exceptions Raised by DBMS_OUTPUT

ORU-10027 Buffer overflow Increase the buffer size if possible.

Otherwise, find a way to write less data.

ORU-10028 Line length Make sure that all calls made to PUT and

overflow, limit of PUT_LINE have fewer than 255 characters.

255 characters per line

Now that you know the exceptions, you can trap errors as they occur

Package

TheUTL_FILEpackage enables you to read and write files on the database server Thereare two prerequisites to using UTL_FILE:

• You must be granted execute privileges on the UTL_FILEpackage

• Your database administrator must set a database initialization parameter namedUTL_FILE_DIR

Granting access to the package is easy If you don’t already have execute privileges onUTL_FILE, your database administrator can grant it by logging on as the user SYS, andissuing a command like this:

GRANT EXECUTE ON utl_file TO username;

INPUT

Trang 16

The matter of the UTL_FILE_DIRparameter is a bit more difficult to explain You can’tjust read and write files in any directory on the server When you make calls toUTL_FILE_DIR, Oracle is really reading and writing the files for you On most systems,

the Oracle software runs in privileged mode, giving it access to all the files Needless to

say, that presents a security risk To mitigate that risk, before UTL_FILEcan be used, yourdatabase administrator must set the UTL_FILE_DIRparameter to point to a specific list ofdirectories All file I/O done by UTL_FILEmust be done in one of those directories Theexamples in this book assume the following setting:

UTL_FILE_DIR = c:\a

If you’re experimenting with UTL_FILEon a workstation, you need to add this line to thedatabase parameter file You also need to stop and restart the database afterward, in orderfor the new setting to take effect

WhenUTL_FILE_DIRis set, and you have been granted EXECUTEaccess to the UTL_FILEpackage, you are ready to read and write files

File Input

UsingUTL_FILE, the overall process to read (or write) a file is as follows:

1 Declare a file handle variable to use in identifying the file when you make calls tothe various UTL_FILEroutines You can use the type UTL_FILE.FILE_TYPEfor thispurpose

2 Declare a string of type VARCHAR2to act as a buffer for reading in the file one line

5 When you’re done, call UTL_FILE.FCLOSEto close the file

The next section talks briefly about the various UTL_FILEprocedures and functions, andshows the syntax information for each Following that is a section with an exampleshowing UTL_FILEbeing used to write data to a file

Trang 17

Using UTL_FILE Procedures and Functions

TheUTL_FILEpackage implements the following procedures and functions:

Procedure

FFLUSH Flushes any buffered data to be written out to disk

immediately

NEW_LINE Writes a newline character out to a file

PUT Writes a string of characters to a file, but doesn’t

follow that with a newline

PUTF Formats and writes output This is a crude

imita-tion of C’sprintf()procedure

Many of the procedure names in the UTL_FILEpackage are named identically to sponding procedures in DBMS_OUTPUT For example,GET_LINEandPUT_LINEare used inboth packages to read and write lines The difference is in whether that I/O is done toand from a file or to and from a memory buffer

corre-TheFCLOSE Procedure

TheFCLOSEprocedure closes a file If the buffer for the file being closed is not empty, it

is flushed to disk before the file is closed

The Syntax for the FCLOSEProcedure

PROCEDURE FCLOSE(file IN OUT file_type);

Thefileparameter is the file handle returned from FOPENwhen the file was originallyopened Table 17.2 shows a list of possible exceptions raised by FCLOSE

Trang 18

T ABLE 17.2 Exceptions Raised by FCLOSE and FCLOSE_ALL

UTL_FILE.INVALID_FILEHANDLE You passed a file handle that didn’t represent an open file

UTL_FILE.WRITE_ERROR The operating system was unable to write to the file.

UTL_FILE.INTERNAL_ERROR An internal error occurred.

The first exception in the list, that of an invalid file handle, is one that you can easily vent simply by being careful to write good code Make sure you open a file before youuse it, and that you keep track of which variable has the file handle in it Write errors canoccur if the disk is full, or if some other error prevents Oracle from writing the data foryou An internal error indicates that Oracle itself is messed up

pre-TheFCLOSE_ALL Procedure

TheFCLOSE_ALLprocedure closes all the files at once, flushing any buffers that are notempty

The Syntax for the FCLOSE_ALL Procedure

PROCEDURE FCLOSEALL;

Refer to Table 17.2 for a list of possible exceptions raised by FCLOSE_ALL You should beaware that although FCLOSE_ALLdoes close all files, it does not mark the files as closed.Future calls to IS_OPENstill indicate that they are open, even though in reality they arenot

TheFOPEN Procedure

FOPENopens a file for reading, or for writing FOPENis a function, and it returns a filehandle pointing to the file that was opened There are two versions of FOPEN One allowsyou to specify a maximum line size, and the other does not

The Syntax for the FOPENProcedureFUNCTION FOPEN(location IN VARCHAR2,

filename IN VARCHAR2, openmode IN VARCHAR2) RETURN FILE_TYPE;

FUNCTION FOPEN(location IN VARCHAR2,

filename IN VARCHAR2, openmode IN VARCHAR2, max_linesize IN BINARY_INTEGER) RETURN FILE_TYPE;

Trang 19

The parameters are as follows:

• locationis the name of the directory containing the file This must match one ofthe directories listed for the UTL_FILE_DIRparameter

• filenameis the name of the file The name can include an extension

• openmodeis the mode in which you are opening the file Valid values are R,W, and

A Use Rto read a file,Wto write to a file, and Ato append to an existing file

• max_linesizeallows you to specify the maximum line size The allowed range is

1 through 32,767 If you omit this parameter, then the default, 1023, is used

The ability to specify a line size in the FOPEN call is a new feature in Oracle8i.

With releases of Oracle prior to 8.1.5, you are limited to a line size of 1023 bytes or less.

If you open a file for write, and a file with the same name exists already, that file is overwritten If you append to a file that does not exist, a new file

is created.

Note

After the file has been successfully opened, the FOPENfunction returns a file handle Youmust use that handle for all further operations on the file FOPENcan raise several excep-tions, which are listed in Table 17.3

T ABLE 17.3 Exceptions Raised by FOPEN

UTL_FILE.INVALID_PATH The directory is not valid You should check it against

UTL_FILE_DIR

UTL_FILE.INVALID_MODE An invalid mode was specified The open mode must be

either R , W , or A

UTL_FILE.INVALID_OPERATION The file could not be opened for some other reason.

Verify that the Oracle software owner has access to the directory (it could be a permissions issue) and contact your database administrator for help.

UTL_FILE.INTERNAL_ERROR An internal error occurred.

If you get the invalid path exception, you need to check your directory path against yourdatabase’sUTL_FILE_DIRparameter setting Remember, you can only write to the specif-

ic directories listed for that parameter The invalid mode exception implies a codingerror To correct it, just modify your code to use one of the valid modes If you get an

Trang 20

invalid operation error, then there is some sort of operating system related reason whyyou can’t open the file Unfortunately, PL/SQL won’t give you any details about whatthat problem is The internal error is something you should never get, and indicates thatOracle is not functioning properly.

TheGET_LINE Function

When performing file input, in order to read data from the file into the buffer, you usetheGET_LINEfunction

The Syntax for the GET_LINEFunction

PROCEDURE GET_LINE(file IN FILE_TYPE,

buffer OUT VARCHAR2);

The parameters are as follows:

• fileis the file handle returned from the FOPEN function when the file was nally opened

origi-• bufferis where the data is placed after it is read from the file This must be oftypeVARCHAR2 Possible errors that could arise are shown in Table 17.4

T ABLE 17.4 Exceptions Raised by GET_LINE

UTL_FILE.INVALID_FILEHANDLE You passed an invalid file handle Possibly you forgot to

open the file first

UTL_FILE.INVALID_OPERATION The file is not open for reading (R mode), or there are

problems with file permissions.

UTL_FILE.VALUE_ERROR The buffer is not long enough to hold the line being read

from the file Increase the size of the buffer.

UTL_FILE.NO_DATA_FOUND The end of file has been reached.

UTL_FILE.INTERNAL_ERROR An error internal to the UTL_FILE system occurred.

UTL_FILE.READ_ERROR An operating system error occurred while reading from

the file

When you use GET_LINEto read a file, the maximum line length that it can handle is theone specified when you opened the file This defaults to 1023 bytes, not including thenewline character The newline characters are stripped out, and aren’t returned to you

TheIS_OPEN Function

TheIS_OPENfunction tests to see if a file is open You can use it before you attempt toopen a file to be sure that it’s not already open You can also test to make sure a file isopen before you attempt to close it

Trang 21

The Syntax for the IS_OPENFunction

FUNCTION IS_OPEN(file IN FILE_TYPE) RETURN BOOLEAN;

If the file is open, the value true is returned; otherwise, false is returned The filemeter is the file handle for the file that you are checking

para-TheNEW_LINE Procedure

TheNEW_LINEprocedure writes one or more newline characters to a file The file must beopen for output (mode AorW) You can’t write newlines to a file that you are reading

This procedure would be used to add a newline character after you have made one ormore calls to the PUTprocedure

The Syntax for the NEW_LINEProcedure

PROCEDURE NEW_LINE(file IN FILE_TYPE,

lines IN NATURAL :=1);

In this syntax the parameters are as follows:

• fileis the file handle returned from FOPENwhen the file was originally opened

• linesis the total number of newline characters you want to write to the file Thedefault is to write one newline This is an optional argument

The same exceptions can be raised for NEW_LINEas are raised with PUT Table 17.5 shows

a list of these

ThePUT Procedure

ThePUTprocedure writes the string to the output file, but without adding a newline acter to the end

char-The Syntax for the PUTProcedure

PROCEDURE PUT(file IN FILE_TYPE,

buffer IN VARCHAR2);

In this syntax the parameters are as follows:

• fileis the file handle as returned from FOPEN

• buffercontains the text you want written to the file The maximum number ofcharacters that you can write using one call is limited to the line size you specified

in the FOPENcall for the file, and defaults to 1023

Table 17.5 lists the exceptions that can be raised by PUT

Trang 22

T ABLE 17.5 Exceptions Raised by PUT , PUT_LINE , PUTF , and FFLUSH

UTL_FILE.INVALID_FILEHANDLE You used an invalid file handle This exception might

be raised if you forgot to open the file

UTL_FILE.INVALID_OPERATION You attempted to write to a file that was not open for

writing (modes W or A ).

UTL_FILE.WRITE_ERROR An operating system error occurred, such as a disk

full error, while attempting to write to the file.

UTL_FILE.INTERNAL_ERROR An internal error occurred.

Most of these exceptions have already been described earlier in this chapter Invalid filehandle and invalid operation exceptions represent coding errors Make sure that you keeptrack of your file handles, and don’t try to write to a file that was only opened for read-ing Write errors represent operating system errors Check for available disk space Youmay have filled up the disk Internal errors indicate a problem with the database softwareitself

ThePUT_LINE Procedure

ThePUT_LINEprocedure writes a string to a file, followed by a newline character.PUT_LINEbasically combines PUTandNEW_LINEinto one procedure

The Syntax for the PUT_LINEProcedure

The procedure header for PUT_LINElooks like this:

PROCEDURE PUT_LINE(file IN FILE_TYPE,

buffer IN VARCHAR2);

In this syntax the parameters are as follows:

• fileis the file handle as returned from FOPEN

• buffercontains the text you want written to the file The maximum number ofcharacters you can write by using one call is limited to the line size you specified

in the FOPENcall and defaults to 1023

PUT_LINEis by far the most commonly used of the PUTprocedures and can raise thesame errors as PUT(refer to Table 17.5)

ThePUTF Procedure

ThePUTFprocedure provides formatted output capabilities similar to those provided bythe C language’sprintf()function However,PUTF’s capabilities pale in comparison toprintf()

Trang 23

The Syntax for the PUTFProcedure

PROCEDURE PUTF(file IN FILE_TYPE,

format IN VARCHAR2, arg1 IN VARCHAR2 DEFAULT NULL, arg2 IN VARCHAR2 DEFAULT NULL, arg3 IN VARCHAR2 DEFAULT NULL, arg4 IN VARCHAR2 DEFAULT NULL, arg5 IN VARCHAR2 DEFAULT NULL);

In this syntax the parameters are as follows:

• fileis the file handle as returned from FOPEN

• formatrepresents the string you want written to the file You can include two cial format characters in this string You use %Sto indicate where the values ofarg1througharg5should be placed You use \nto indicate where newline charac-ters should be placed

spe-• arg1 arg5are optional arguments containing values that are substituted into theformat string before it is written to the file The first %Sfound in the format string

is replaced by the value of arg1, the second %Sby the value of arg2, and so forth

PUTFcan raise the same exceptions as PUT(refer to Table 17.5)

Understanding argument substitution is the key to understanding PUTF The argumentsrepresented by arg1througharg5are substituted for occurrences of %Sin the formatstring This substitution is done based on the order in which the arguments are listed Thevalue for arg1replaces the first use of %S The value for arg2replaces the second use of

%S, and so on Here are some examples:

The call represents a possible call to the PUTFprocedures The results show what wouldactually be written to the file

Trang 24

ThePUTFfunction does not automatically write a newline character If you want a line written, you must indicate that by placing \nat the end of the formatstring.

new-Alternatively, you could make a separate call to UTL_FILE.NEW_LINE

TheFFLUSH Procedure

When you use any of the PUTcommands, the data is stored in the UTL_FILEpackage’sbuffer until the buffer is full, and then the contents are written to the file If you need toflush the contents of the buffer immediately, you can call the FFLUSHprocedure

The Syntax for the FFLUSHProcedure

PROCEDURE FFLUSH(file IN FILE_TYPE);

Thefileparameter is the file handle returned from FOPENwhen the file was originallyopened Refer to Table 17.5 for a list of possible exceptions raised by FFLUSH

An Example of Using UTL_FILE

Suppose you wanted to generate a file that contains employee ID numbers and names,and that you want that data in comma-delimited format You can do that by usingUTL_FILEin conjunction with some PL/SQL code of your own

The first step in writing such a procedure is to declare a file handle to use in identifyingthe file

The Syntax for Creating a File Handle

DECLARE handle_name UTL_FILE.FILE_TYPE;

BEGINThe type UTL_FILE.FILE_TYPEis a PL/SQL record defined by the UTL_FILEpackage

It contains information that UTL_FILEneeds to know about the file The variable handle_nameis referred to as a file handle Replace handle_namewith a variable name

of your choosing The file handle needs to be passed to every UTL_FILEroutine that ates on the file

oper-After declaring the file handle, your next step might be to code the open and close logic,

as well as the error handling Listing 17.4 shows what this might look like

If you need to output more than five arguments, just call the PUTF ment as many times in a row as necessary.

Trang 25

L ISTING 17.4 The Core File-Handling Logic

1: DECLARE 2: emp_data UTL_FILE.FILE_TYPE;

3: BEGIN 4: Open the file 5: emp_data := UTL_FILE.FOPEN (‘c:\a’,’empdata.csv’,’W’);

13: (‘UTL_FILE: An internal error occurred.’);

30: UTL_FILE.FCLOSE_ALL;

31: WHEN UTL_FILE.read_error THEN 32: DBMS_OUTPUT.PUT_LINE 33: (‘UTL_FILE: A read error occurred.’);

34: UTL_FILE.FCLOSE_ALL;

35: WHEN UTL_FILE.write_error THEN 36: DBMS_OUTPUT.PUT_LINE 37: (‘UTL_FILE: A write error occurred.’);

38: UTL_FILE.FCLOSE_ALL;

This listing, and all the others related to UTL_FILE , use the c:\a directory.

You either need to create that directory, or change the code to reference a directory that exists in your environment You also need to be sure that the

UTL_FILE_DIR parameter setting lists the directory that you are using.

Note

INPUT

continues

Ngày đăng: 15/12/2013, 05:15

TỪ KHÓA LIÊN QUAN