• Tidak ada hasil yang ditemukan

Identifiers

Dalam dokumen Buku Oracle PL/SQL (Third Edtion) (Halaman 63-67)

Show Other Errors

Chapter 3. Language Fundamentals

3.3 Identifiers

An identifier is a name for a PL/SQL object, including any of the following:

l Constant

l Scalar variable

l Composite variable (record or collection)

l Exception

l Procedure

l Function

l Package

l Type

l Cursor

l Reserved word

l Label

Default properties of PL/SQL identifiers are summarized below:

l Up to 30 characters in length

l Must start with a letter

l Can include $ (dollar sign), _ (underscore), and # (pound sign)

l Cannot contain spaces

If the only difference between two identifiers is the case of one or more letters, PL/SQL normally treats those two identifiers as the same.[1] For example, the following identifiers are all considered by PL/SQL to be the same:

[1] The compiler accomplishes this by internally converting program text into uppercase during an early compiler phase.

lots_of_$MONEY$

LOTS_of_$MONEY$

Lots_of_$Money$

The following strings are valid names of identifiers:

company_id#

primary_acct_responsibility First_Name

FirstName address_line1 S123456

The following identifiers are all illegal in PL/SQL:

1st_year -- Starts with numeral procedure-name -- Contains invalid character "-"

minimum_%_due -- Contains invalid character "%"

maximum_value_exploded_for_detail -- Name is too long

company ID -- Cannot have embedded spaces in name

Identifiers are the handles for objects in your program. Be sure to name your objects carefully so the names describe the objects and their uses. Avoid identifier names like X1 and temp; they are too ambiguous to mean anything to you or to anyone else reading your code.

Although rarely done in practice, you can actually break some of these rules by surrounding identifiers with double quotation marks. I don't recommend programming like this, but you may one day have to deal with some "clever" code such as:

SQL> DECLARE

2 "pi" CONSTANT NUMBER := 3.141592654;

3 "PI" CONSTANT NUMBER := 3.14159265358979323846;

4 "2 pi" CONSTANT NUMBER := 2 * "pi";

5 BEGIN

6 DBMS_OUTPUT.PUT_LINE('pi: ' || "pi");

7 DBMS_OUTPUT.PUT_LINE('PI: ' || pi);

8 DBMS_OUTPUT.PUT_LINE('2 pi: ' || "2 pi");

9* END;

10 /

pi: 3.141592654

PI: 3.14159265358979323846 2 pi: 6.283185308

Notice that line 7 refers to pi without quotation marks. Because the compiler accomplishes its case-independence by defaulting identifiers and keywords to uppercase, the variable that line 7 refers to is the one declared on line 3 as "PI".

On rare occasions, you may need to use the double-quote trick in SQL statements to refer to database objects that exist with mixed-case names. I've seen this happen when a programmer used Microsoft Access to create the Oracle tables.

3.3.1 Reserved Words

Of course, you don't get to name all the identifiers in your programs. The PL/SQL language recognizes certain identifiers (such as BEGIN, IF, and THEN) as having special meaning.

There are two kinds of built- in identifiers that PL/SQL provides:

l Language keywords

l Identifiers from the STANDARD package

In both cases you should not—and, in many cases, cannot—redefine the identifier for your program's own use.

3.3.1.1 Language keywords

The PL/SQL compiler recognizes certain words as having certain semantics no matter what. For example, one very important reserved word is END, which terminates programs, IF statements, and loops. If you try to declare a variable named "end", as I do below:

DECLARE

end VARCHAR2(10) := 'blip'; /* Will not work! Can't use END as name. */

BEGIN

DBMS_OUTPUT.PUT_LINE (end);

END;

/

then you will get the subsequent compile error:

PLS-00103: Encountered the symbol "END" when expecting one of the following:

The appearance of the word "end" in the declaration section signals to PL/SQL the premature termination of that anonymous block.

3.3.1.2 Identifiers from STANDARD package

In addition to avoiding identifiers that duplicate keywords, you should also avoid using identifiers that duplicate names Oracle has defined in a special package named STANDARD. Oracle defines quite a few identifiers in this package, including built-inexceptions like DUP_VAL_ON_INDEX,functions like UPPER, REPLACE, and TO_DATE, andsubtypes such as STRING. You can view a list of functions and procedures defined in STANDARD with this command:

SQL> DESC SYS.STANDARD

You may occasionally find that you want to use the name of a built- in from STANDARD. You can still reference the built-in form by prefixing it with STANDARD, as follows:

DECLARE

dup_val_on_index EXCEPTION; -- local re-declaration BEGIN

...

INSERT INTO ... /* may raise the built-in exception */

...

RAISE dup_val_on_index; -- resolves to the locally declared exception EXCEPTION

WHEN dup_val_on_index THEN

/* handle the locally declared exception */

...

WHEN STANDARD.DUP_VAL_ON_INDEX THEN

/* handle the usual exception */

...

END;

3.3.1.3 Approaches to avoiding reserved words

Finding a valid name for your identifier should be the least of your problems, as there are thousands and thousands of permutations of the legal characters. The question is, how will you know if you inadvertently use a reserved word in your own program? By some counts, there are hundreds of words known to PL/SQL!

You could just ignore this issue and deal with the compiler errors as they come up. This is what a lot of people do, but it can be a real drain on a workday because sometimes the error messages are completely off the wall. Some people use a high-priced development environment with a snazzy syntax-directed editor that alerts you to possible problems as you type. Personally, my favorite solution is to use a cheap (as in free) editor that is aware of PL/SQL's keywords and just highlights them automatically.[2]

[2] As a matter of fact, I helped create a syntax highlighting file and an automatic indentation file for an open source editor known as vim (derived from vi). Very cool.

Visit the book's web site for details.

I have compiled a small list of the Oracle9i PL/SQL reserved words, shown in Table 3-4 (and available in the reserved.txt file on the O'Reilly site). Starting from the list of keywords Oracle publishes in the V$RESERVED_WORDS data dictionary view, I tried to declare a variable, and then a procedure, using the word as its identifier. If the compiler prevented me doing from one or both of those operations, I put the keyword on the list.

Table 3-4. Absolute minimal list of words to avoid using as PL/SQL identifiers ACCESS

ADD ALL ALTER AND ANY AS ASC AT AUDIT BEGIN BETWEEN BY

CASE CHAR CHECK CLOSE CLUSTER COLUMN COLUMNS COMMENT COMMIT COMPRESS CONNECT CREATE CURRENT DEFAULT

CURSOR DATE DECIMAL DECLARE DEFAULT DELETE DESC DISTINCT DROP ELSE END

EXCLUSIVE EXISTS FILE FLOAT FOR FROM FUNCTION GRANT GROUP HAVING IDENTIFIED IF

IMMEDIATE IN

INCREMENT INDEX

INDEXES INITIAL INSERT INTEGER INTERSECT INTO

IS LEVEL LIKE LOCK LONG

MAXEXTENTS MINUS

MLSLABEL MODE MODIFY NOAUDIT NOCOMPRESS NOT

NOWAIT NULL NUMBER OF

OFFLINE ON

ONLINE OPEN

OPTION OR ORDER OVERLAPS PACKAGE PCTFREE PRIOR

PRIVILEGES PROCEDURE PUBLIC RAW RENAME RESOURCE RETURN REVOKE ROLLBACK ROW

ROWID ROWNUM ROWS

SAVEPOINT SELECT SESSION SET SHARE SIZE SMALLINT

START

SUCCESSFUL SYNONYM SYSDATE TABLE THEN TO

TRIGGER TYPE UID UNION UNIQUE UPDATE USE USER VALIDATE VALUES VARCHAR VARCHAR2 VIEW WHEN WHENEVER WHERE WITH

If you are running Oracle 8.1.5 or later, you can ask your DBA to grant you privilege to execute this statement:

SQL> SELECT * FROM V$RESERVED_WORDS;

Although the list is overwhelmingly long, it does not even include all the identifiers in STANDARD; the PL/SQL compiler does not care if you carelessly reuse identifiers declared there. All the more reason to use an intelligent editor.

3.3.2 Whitespace and Keywords

Identifiers must be separated by at least one space or by a delimiter, but you can format your text by adding additional spaces, line breaks (newlines and/or carriage returns), and tabs wherever you can put a space, without changing the meaning of your entry.

The two statements shown below are therefore equivalent:

IF too_many_orders THEN

warn_user;

ELSIF no_orders_entered THEN

prompt_for_orders;

END IF;

IF too_many_orders THEN warn_user;

ELSIF no_orders_entered THEN prompt_for_orders;

END IF;

You may not, however, place a space or carriage return or tab within a lexical unit, such as a compound delimiter like the "not equals" symbol (!=). The following statement raises a compile error:

IF max_salary ! = min_salary THEN because there is a space between the ! and the =.

Dalam dokumen Buku Oracle PL/SQL (Third Edtion) (Halaman 63-67)