Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Avoiding Inner Capture in DML Statements

In the following example, the reference to col2 in the inner SELECT statement binds to column col2 in table tab1 because table tab2 has no column named col2:

CREATE TABLE tab1 (col1 NUMBER, col2 NUMBER); CREATE TABLE tab2 (col1 NUMBER);

CREATE PROCEDURE proc AS

CURSOR c1 IS SELECT * FROM tab1

WHERE EXISTS (SELECT * FROM tab2 WHERE col2 = 10);

BEGIN

...

END;

In the preceding example, if you add a column named col2 to table tab2:

ALTER TABLE tab2 ADD (col2 NUMBER);

then procedure proc is invalidated and recompiled automatically upon next use. However, upon recompilation, the col2 in the inner SELECT statement binds to column col2 in table tab2 because tab2 is in the inner scope. Thus, the reference to col2 is captured by the addition of column col2 to table tab2.

Using collections and object types can cause more inner capture situations. In the following example, the reference to s.tab2.a resolves to attribute a of column tab2 in table tab1 through table alias s, which is visible in the outer scope of the query:

CREATE TYPE type1 AS OBJECT (a NUMBER); CREATE TABLE tab1 (tab2 type1);

CREATE TABLE tab2 (x NUMBER);

SELECT * FROM tab1 s -- alias with same name as schema name WHERE EXISTS (SELECT * FROM s.tab2 WHERE x = s.tab2.a);

-- note lack of alias

In the preceding example, you might add a column named a to table s.tab2, which appears in the inner subquery. When the query is processed, an inner capture occurs because the reference to s.tab2.a resolves to column a of table tab2 in schema s. You can avoid inner captures by following the rules given in "Avoiding Inner Capture in DML Statements" on page D-4. According to those rules, you should revise the query as follows:

SELECT * FROM s.tab1 p1

WHERE EXISTS (SELECT * FROM s.tab2 p2 WHERE p2.x = p1.tab2.a);

Same-Scope Capture

In SQL scope, a same-scope capture occurs when a column is added to one of two tables used in a join, so that the same column name exists in both tables. Previously, you could refer to that column name in a join query. To avoid an error, now you must qualify the column name with the table name.

Outer Capture

An outer capture occurs when a name in an inner scope, which once resolved to an entity in an inner scope, is resolved to an entity in an outer scope. SQL and PL/SQL are designed to prevent outer captures. You do not need to take any action to avoid this condition.

Avoiding Inner Capture in DML Statements

You can avoid inner capture in DML statements by following these rules:

D-4 PL/SQL User's Guide and Reference

Calling Parameterless Subprograms and Methods

Specify an alias for each table in the DML statement.

Keep table aliases unique throughout the DML statement.

Avoid table aliases that match schema names used in the query.

Qualify each column reference with the table alias.

Qualifying a reference with schema_name.table_name does not prevent inner capture if the statement refers to tables with columns of a user-defined object type.

Qualifying References to Object Attributes and Methods

Columns of a user-defined object type allow for more inner capture situations. To minimize problems, the name-resolution algorithm includes the following rules:

All references to attributes and methods must be qualified by a table alias. When referencing a table, if you reference the attributes or methods of an object stored in that table, the table name must be accompanied by an alias. As the following examples show, column-qualified references to an attribute or method are not allowed if they are prefixed with a table name:

CREATE TYPE t1 AS OBJECT (x NUMBER);

 

CREATE TABLE tb1 (col t1);

 

SELECT col.x FROM tb1;

-- not allowed

SELECT tb1.col.x FROM tb1;

-- not allowed

SELECT scott.tb1.col.x FROM scott.tb1;

-- not allowed

SELECT t.col.x FROM tb1 t;

 

UPDATE tb1 SET col.x = 10;

-- not allowed

UPDATE scott.tb1 SET scott.tb1.col.x=10;

-- not allowed

UPDATE tb1 t set t.col.x = 1;

 

DELETE FROM tb1 WHERE tb1.col.x = 10;

-- not allowed

DELETE FROM tb1 t WHERE t.col.x = 10;

 

Row expressions must resolve as references to table aliases. You can pass row expressions to operators REF and VALUE, and you can use row expressions in the SET clause of an UPDATE statement. Some examples follow:

CREATE TYPE t1 AS OBJECT (x number);

 

CREATE TABLE ot1 OF t1;

-- object table

SELECT REF(ot1) FROM ot1;

-- not allowed

SELECT REF(o) FROM ot1 o;

 

SELECT VALUE(ot1) FROM ot1;

-- not allowed

SELECT VALUE(o) FROM ot1 o;

 

DELETE FROM ot1 WHERE VALUE(ot1) = (t1(10));

-- not allowed

DELETE FROM ot1 o WHERE VALUE(o) = (t1(10));

 

UPDATE ot1 SET ot1 = ...

-- not allowed

UPDATE ot1 o SET o = ....

 

The following ways to insert into an object table are allowed and do not require an alias because there is no column list:

INSERT

INTO

ot1

VALUES

(t1(10)); --

no

row

expression

INSERT

INTO

ot1

VALUES

(10);

--

no

row

expression

Calling Parameterless Subprograms and Methods

If a subprogram does not take any parameters, you can include an empty set of parentheses or omit the parentheses, both in PL/SQL and in functions called from SQL queries.

How PL/SQL Resolves Identifier Names D-5

Name Resolution for SQL Versus PL/SQL

For calls to a method that takes no parameters, an empty set of parentheses is optional within PL/SQL scopes but required within SQL scopes.

Name Resolution for SQL Versus PL/SQL

The name-resolution rules for SQL and PL/SQL are similar. You can avoid the few minor differences if you follow the capture avoidance rules.

For compatibility, the SQL rules are more permissive than the PL/SQL rules. That is, the SQL rules, which are mostly context sensitive, recognize as legal more situations and DML statements than the PL/SQL rules do.

D-6 PL/SQL User's Guide and Reference

E

PL/SQL Program Limits

This appendix discusses the program limits that are imposed by the PL/SQL language.

PL/SQL is based on the programming language Ada. As a result, PL/SQL uses a variant of Descriptive Intermediate Attributed Notation for Ada (DIANA), a tree-structured intermediate language. It is defined using a meta-notation called Interface Definition Language (IDL). DIANA is used internally by compilers and other tools.

At compile time, PL/SQL source code is translated into machine-readable m-code. Both the DIANA and m-code for a procedure or package are stored in the database. At run time, they are loaded into the shared memory pool. The DIANA is used to compile dependent procedures; the m-code is simply executed.

In the shared memory pool, a package spec, object type spec, standalone subprogram, or anonymous block is limited to 2**26 DIANA nodes (which correspond to tokens such as identifiers, keywords, operators, and so on). This allows for ~6,000,000 lines of code unless you exceed limits imposed by the PL/SQL compiler, some of which are given in Table E–1.

Table E–1 PL/SQL Compiler Limits

Item

Limit

 

 

bind variables passed to a program unit

32K

exception handlers in a program unit

64K

fields in a record

64K

levels of block nesting

255

levels of record nesting

32

levels of subquery nesting

254

levels of label nesting

98

magnitude of a BINARY_INTEGER value

2G

magnitude of a PLS_INTEGER value

2G

objects referenced by a program unit

64K

parameters passed to an explicit cursor

64K

parameters passed to a function or procedure

64K

precision of a FLOAT value (binary digits)

126

precision of a NUMBER value (decimal digits)

38

PL/SQL Program Limits E-1

Table E–1

(Cont.) PL/SQL Compiler Limits

 

 

Item

Limit

precision of a REAL value (binary digits) size of an identifier (characters)

size of a string literal (bytes) size of a CHAR value (bytes) size of a LONG value (bytes) size of a LONG RAW value (bytes) size of a RAW value (bytes)

size of a VARCHAR2 value (bytes) size of an NCHAR value (bytes)

size of an NVARCHAR2 value (bytes) size of a BFILE value (bytes)

size of a BLOB value (bytes)

size of a CLOB value (bytes)

size of an NCLOB value (bytes)

63

30

32K

32K

32K-7

32K-7

32K

32K

32K

32K

4G * value of DB_BLOCK_SIZE parameter

4G * value of DB_BLOCK_SIZE parameter

4G * value of DB_BLOCK_SIZE parameter

4G * value of DB_BLOCK_SIZE parameter

To estimate how much memory a program unit requires, you can query the data dictionary view user_object_size. The column parsed_size returns the size (in bytes) of the "flattened" DIANA. For example:

SQL> SELECT * FROM user_object_size WHERE name = 'PKG1';

NAME TYPE SOURCE_SIZE PARSED_SIZE CODE_SIZE ERROR_SIZE

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

PKG1

PACKAGE

46

165

119

0

PKG1

PACKAGE BODY

82

0

139

0

Unfortunately, you cannot estimate the number of DIANA nodes from the parsed size. Two program units with the same parsed size might require 1500 and 2000 DIANA nodes, respectively (because, for example, the second unit contains more complex SQL statements).

When a PL/SQL block, subprogram, package, or object type exceeds a size limit, you get an error such as program too large. Typically, this problem occurs with packages or anonymous blocks. With a package, the best solution is to divide it into smaller packages. With an anonymous block, the best solution is to redefine it as a group of subprograms, which can be stored in the database.

E-2 PL/SQL User's Guide and Reference

F

List of PL/SQL Reserved Words

The words listed in this appendix are reserved by PL/SQL. You should not use them to name program objects such as constants, variables, or cursors. Some of these words (marked by an asterisk) are also reserved by SQL. You should not use them to name schema objects such as columns, tables, or indexes.

List of PL/SQL Reserved Words F-1

ALL*

FUNCTION

PLS_INTEGER

VARCHAR*

ALTER*

GOTO

POSITIVE

VARCHAR2*

AND*

GROUP*

POSITIVEN

VARIANCE

ANY*

HAVING*

PRAGMA

VIEW*

ARRAY

HEAP

PRIOR*

WHEN

AS*

HOUR

PRIVATE

WHENEVER*

ASC*

IF

PROCEDURE

WHERE*

AT

IMMEDIATE*

PUBLIC*

WHILE

AUTHID

IN*

RAISE

WITH*

AVG

INDEX*

RANGE

WORK

BEGIN

INDICATOR

RAW*

WRITE

BETWEEN*

INSERT*

REAL

YEAR

BINARY_INTEGER

INTEGER*

RECORD

ZONE

BODY

INTERFACE

REF

 

BOOLEAN

INTERSECT*

RELEASE

 

BULK

INTERVAL

RETURN

 

BY*

INTO*

REVERSE

 

CASE

IS*

ROLLBACK

 

CHAR*

ISOLATION

ROW*

 

CHAR_BASE

JAVA

ROWID*

 

CHECK*

LEVEL*

ROWNUM*

 

CLOSE

LIKE*

ROWTYPE

 

CLUSTER*

LIMITED

SAVEPOINT

 

COALESCE

LOCK*

SECOND

 

COLLECT

LONG*

SELECT*

 

COMMENT*

LOOP

SEPARATE

 

COMMIT

MAX

SET*

 

COMPRESS*

MIN

SHARE*

 

CONNECT*

MINUS*

SMALLINT*

 

CONSTANT

MINUTE

SPACE

 

CREATE*

MLSLABEL*

SQL

 

CURRENT*

MOD

SQLCODE

 

CURRVAL

MODE*

SQLERRM

 

CURSOR

MONTH

START*

 

DATE*

NATURAL

STDDEV

 

DAY

NATURALN

SUBTYPE

 

DECLARE

NEW

SUCCESSFUL*

 

DECIMAL*

NEXTVAL

SUM

 

DEFAULT*

NOCOPY

SYNONYM*

 

DELETE*

NOT*

SYSDATE*

 

DESC*

NOWAIT*

TABLE*

 

DISTINCT*

NULL*

THEN*

 

DO

NULLIF

TIME

 

DROP*

NUMBER*

TIMESTAMP

 

ELSE*

NUMBER_BASE

TIMEZONE_REGION

 

ELSIF

OCIROWID

TIMEZONE_ABBR

 

END

OF*

TIMEZONE_MINUTE

 

EXCEPTION

ON*

TIMEZONE_HOUR

 

EXCLUSIVE*

OPAQUE

TO*

 

EXECUTE

OPEN

TRIGGER*

 

EXISTS*

OPERATOR

TRUE

 

EXIT

OPTION*

TYPE

 

EXTENDS

OR*

UID*

 

EXTRACT

ORDER*

UNION*

 

FALSE

ORGANIZATION

UNIQUE*

 

FETCH

OTHERS

UPDATE*

 

FLOAT*

OUT

USE

 

FOR*

PACKAGE

USER*

 

FORALL

PARTITION

VALIDATE*

 

FROM*

PCTFREE*

VALUES*

 

F-2 PL/SQL User's Guide and Reference

Соседние файлы в папке Oracle 10g