Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
:
, , ,
,
DiaSoft
-
2005
681.3. 06(075)
32.973.2
88
88 Oracle PL/SQL : / ,
, . ; . . - . : , 2005. 560 .
ISBN 5-93772-160-8
Apress Oracle.
OakTable Press Oracle. Apress
, -
, -
.
Oracle PL/SQL PL/SQL.
PL/SQL. ,
, -
. , -
PL/SQL, , ,
, HTML- -
. , , -
, PL/SQL .
32.973.2
Original English language edition published by Apress, 2560 Ninth Street, Suite 219, Berkeley, CA 94710
USA.
Copyright 2004 by Apress
Russian-language edition copyright 2005 by Diasoft Publishing. All rights reserved.
Apress.
,
.
, . -
, -
. ,
.
, , .
-
.
ISBN 5-93772-160-8 (.) . , 2005
ISBN 1-59059-217-4 (.) Apress, 2004
. , 2005
77.99.6.953..438.2.99 04.02.1999
Press 11
13
15
16
17
20
SCOTT/TIGER 20
SQL*Plus 20
AUTOTRACE SQL*Plus 22
23
TIMED_STATISTICS 24
SQLJRACE TKPROF 24
RUNSTATS 28
! PL/SQL 37
PL/SQL? 37
PL/SQL 38
38
" PL/SQL"? 40
40
42
42
48
49
PL/SQL 59
PL/SQL SQL 64
PL/SQL-? 84
84
2. 87
87
89
90
91
91
92
99
101
103
113
? 114
115
, 115
119
121
123
126
DDL 127
DBMS_ROWID 131
132
135
3. 137
137
139
145
N 148
150
150
151
154
159
4. 161
161
%TYPE 162
166
167
%ROWTYPE 169
DML 174
175
177
Runstats 178
PL/SQL 187
191
191
195
PL/SQL- 205
, %TYPE
%ROWTYPE 205
210
PL/SQL 218
223
223
DDL 224
SELECT 226
, 229
231
7
5. PL/SQL 233
233
233
238
: 246
: 254
254
256
DML 259
PL/SQL- 266
PL/SQL , . 266
PL/SQL 278
SQL PL/SQL 283
SQL- SQL 283
SQL 288
299
6. 301
301
302
303
303
305
DML- BEFORE AFTER 305
307
307
309
310
310
310
DML 311
312
312
314
INSTEAD OF 315
318
320
323
324
326
327
329
Oracle Streams 331
( ) 336
337
DML 338
8
339
341
DDL 342
DDL 343
DDL 344
346
346
347
348
349
349
350
351
7. 353
354
355
355
357
360
364
366
367
370
372
375
: 376
376
SEND_EMAIL 377
379
: 380
381
382
383
385
: 386
387
388
390
391
: 393
393
8. 395
395
395
410
, 414
416
417
418
: 425
428
429
432
PL/SQL- Wrap 432
436
9. Web- 439
PL/SQL Web Toolkit 439
440
441
SQL*Plus 442
HTF 443
445
450
451
Web 456
HTTP- 466
HTML- 467
Web- UTL_HTTP 468
473
10. PL/SQL 475
475
475
481
481
482
DBMS_OUTPUT 482
SQLCODE SQLERRM 487
DBMS_UTILITYFORMAT_CALL_STACK 488
DBMS_APPLICATION_INFO 489
495
UTL_FILE 498
501
DEBUG 505
506
506
507
508
509
513
516
10
DEBUG? 518
519
. DEBUG 521
...521
521
522
522
DIRECTORY 523
524
525
F() 525
TnnARGV 526
FA() 527
DEBUG_IT() 527
529
WHO_CALLED_ME() 529
BUILDJTQ 532
PARSEJTQ 534
FILEJTQ 537
INITQ 538
CLEAR() 541
STATUS0 541
542
DEBUG 543
: 543
: 543
544
545
OakTable Press
, OakTable (OakTable Network) -
, Oracle, -
Oracle. Apress OakTable
Press no Oracle.
. -
Oracle. , -
. " ", ,
. . ,
, , OakTable Press
(, , ). / -
, , OakTable. -
OakTable Press , , -
.
.
OakTable Network?
- 1998 , Oracle,
(Anjo Kolk), ( Millsap), (James
Morle) , .
(Scotch) (Bourbon), -
- .
, ,
, , .., Oracle, -
, ,
. 2002 . -
, 16 -
Oracle. -
.
OakTable Network ( ), -
h t t p : //www.OakTable.net .
OakTable 42 ,
Oracle ( ).
, , , , -
(Steve Adams), (Jonathan Lewis) , -
.
-
, OakTable
J2 OakTable Press
. 24 -
, " OakTable ",
, ! --
: , - Miracle (
: 2001 , 2002- , 2003-
, 2004- ), ,
-, Miracle Database Forum,
.
OakTable ,
(, Hotsos Clinic), -
. OakTable Press. ,
, .
,
(Mogens Norgaard)
Miracle A/S (http://www.miracleas.dk/) -
OakTable.
'
\-
, ,
Oracle 1990- . -
Oracle 6.0.36 7.0.12. 11
, -
, - , .
OakTable
Oracle, -
Oracle. Web-
( h t t p : //www.oracledba.co.uk),
Oracle -
.
, Oracle (Oracle Certified
Professional), Oracle, 4. -
PL/SQL Oracle
. Logo
. , , 9- 17-
, ,
. (Ruthie) -
.
,
(Rutgers University), 13 . -
Ada -
, , 9 -
Oracle, .
Web-. -
Oracle
, Linux Quake III
Arena.
Oracle. -
14 ,
SGML , -
. Oracle HTML DB -
, Web-
.
, , ,
.
(The Ohio State University), -
. (Powell), .
14
(Information Assurance
Center) Oracle. 1995 . -
, -
(U.S. Department of Defense DoD), -
, ,
. -
-
Oracle , -
, , LDAP PKI.
(University of Maryland) -
(John
Hopkins University).
- (Jakob Hammer-Jakobsen) 1965 . 1992
, Oracle 1986 ( Oracle 5).
, , - Oracle (
), . -
, Oracle, ;
" Java-". Oracle (Oracle
Certified Developer) OakTable.net. -
, (University of Roskilde),
(International Student Foundation) ,
Pedersen International ( Oracle ), Oracle
, Miracle Australia Miracle Denmark.
(Torben Holm) OakTable. -
1988 , -
. Oracle 1992 : 4 -
( Oracle 7, Forms 4.0/Reports 2.0 DBA), 2
(Oracle 6/7, Forms 3.0, RPT DBA), 2 -
Oracle , Prime Services .
. -
PL/SQL, SQL, WebDB.
3 Miracle A/S ( h t t p : / /www. m i r a c l e a s . dk/)
. Oracle
Developer 6 ( Oracle 8 , -
, ). "-
" PL/SQL.
(Tom Kyte) - (VP, Core
Technologies) Oracle, 16-
Internet-. -
, ,
. Oracle
Magazine, Web- AskTom ( h t t p : //asktom. o r a c l e . com/),
.
"Effective Oracle by Design" (
Oracle), "Expert One-on-One Oracle" ( -
Oracle;
"Oracle " "" 2003
. . .), "Beginning Oracle" -
Oracle.
-, OakTable,
. ,
(, , -
!) . "" .
, , (Dave
Ensor) , Oracle, a
, "" OakTable, -
! , (Tony Davis), no
,
, , .
, , Oracle.
PL/SQL Oracle, -
,
Oracle.
:
, Oracle, ,
. , -
, , ,
, , -
.
Apress ,
. , !
. -
!
, .
" ",
. Oracle,
(Patrick Sack), .
, ,
.
, PL/SQL
38 . ! , -
.
-
?
, , , -
PL/SQL -
Oracle. Oracle .
, , ,
. -
Oracle,
.
PL/SQL ,
.
PL/SQL . ,
PL/SQL ,
(
). , ,
.
-
, -
.
. PL/SQL,
-, PL/SQL .
?
, , -
PL/SQL
. , , , , PL/SQL
, Oracle,
- .
, Oracle, 8/ lOg.
Oracle 9/ R2,
SQL*Plus.
, -
.
. ,
SQL*Plus, , -
, : AUTOTRACE, SQL_TRACE,
TKPROF RUNSTATS.
18
1. PL/SQL. , -
" PL/SQL",
; , ,
-
. , PL/SQL -
, , PL/SQL -
, SQL,
.
2. . , "-
". -
-
. ,
Oracle.
3. .
. ,
. -
-
.
4. . ,
PL/SQL-
. -
.
5. PL/SQL. -
PL/SQL. ,
, "",
.
6. . -
. -
Oracle Streams -
.
7. .
,
, ,
, ,
.
8. . PL/SQL-
. -
,
, ,
.
19
9. Web-. -
PL/SQL Web Toolkit -
Web-
. "" (cookies), -
, Web- (Web Service)
PL/SQL.
10. PL/SQL. -
,
PL/SQL, DBMS_OUTPUT -
DBMS_APPLICATION_INFO UTL_FILE. -
DEBUG .
. DEBUG. -
DEBUG, 10.
?
,
,
Oracle. ,
Oracle ,
PL/SQL.
PL/SQL, -
, .
. , ,
, -
PL/SQL-.
. :
> SCOTT/TIGER;
> SQL*Plus;
> AUTOTRACE SQL*Plus ,
Oracle , -
;
> SQL_TRACE, TIMED_STATISTICS -
TKPROF, , SQL- -
;
> RUNSTATS.
-
,
. -
, , -
Oracle "Expert -- Oracle" (Apress, ISBN:
1-59059-243-3; "Oracle "
"" 2003 . . .).
SCOTT/TIGER
, EMP/DEPT
SCOTT. , -
-
. SCOTT
:
1. cd [ORACLE_HOME] /sqipius/demo;
2. SQL*Plus;
3. SDEMOBLD.SQL.
DEMOBLD. SQL .
SQL*Plus, -
, SQL*Plus .
, [ORACLE_HOME] /
sqlplus/demo/demodrop.sql.
SQL*Plus
SQL*Plus. SQL*Plus
,
21
. DBMS_OUTPUT.
DBMSOUTPUT, SQL*Plus:
SQL> set serveroutput on
SQL*Plus LOGIN.SQL , -
SQL*Plus. -
SERVEROUTPUT, .
LOGIN.SQL (
).
define _editor=vi
set trimspool on
set long 5000
set linesize 100
set pagesize 9999
column plan_plus_exp format a80
, -
SQL*Plus , ,
. , -
:
scott@oracle9i_test>
, SCOTT
ORACLE9I_TEST. LOGIN.SQL,
:
column global_name new_value gname
set termout off
s e l e c t lower(user) | | '@' | |
global_name from global_name;
set sqlprompt '&gname> '
set termout on
. ,
SCOTT, -
, SQL*Plus .
CONNECT . SQL :
set termout off
connect &1
@login
set termout on
(
login) :
scott@ORATEST> @connect tony/davis
tony@ORATEST>
SQL*Plus LOGIN ,
( CONNECT.SQL), a
SQLPATH , -
. Windows, Start, Run
regedit. HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE
SQLPATH ( ). -
, (,
:\oracle\ora81\sqlplus\admin).
AUTOTRACE SQL*Plus
-
, AUTOTRACE SQL*P1US -
,
. -
DML. , AUTOTRACE
,
:
1. $ORACLE_HOME/rdbms/admin ( Windows -
cd %ORACLE_HOME%\rdbms\admin. . .).
2. SQL*Plus CRE:ATE
TABLE CREATE PUBLIC SYNONYM;
3. @UTLXPLAN PLAN_TABLE, -
AUTOTRACE;
4. CREATE PUBLIC SYNONYM PLAN_TABLE FOR PLANJTABLE,
;
5. GRANT ALL ON PLAN_TABLE TO PUBLIC, -
;
23
6. SQL*Plus $ORACLE_HOME/sqlplus/admin;
7. SQL*Plus SYSDBA;
8. @PLUSTRCE;
9. GRANT PLUSTRACE TO PUBLIC.
, AUTOTRACE -
:
SQL> set AUTOTRACE traceonly
SQL> select * from emp, dept
2 where emp.deptno=dept.deptno;
14 rows selected.
Execution Plan
Statistics
0 recursive calls
8 db block gets
2 consistent gets
0 physical reads
0 redo size
2144 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
14 rows processed
AUTOTRACE -
. 11 Oracle 9i Database Performance Tuning Guide and Reference
9 SQL*Plus User's Guide and Reference
Oracle.
AUTOTRACE,
.
.
24
TIMEDJTATISTICS
TIMED_STATISTICS , Oracle
. -
, . -
, TIMED_STATISTICS (
INIT.ORA) . -
, . -
INIT.ORA , -
:
timed_statistics=true
:
SQL> alter session set timed_statistics=true;
SQL_TRACE TKPROF
SQLJTRACE TKPROF -
. : SQL_TRACE -
SQL- -
.
. TKPROF
.
SQL_TRACE
SQL_TRACE SQL- -
. -
, Oracle SQL--
. SQL_TRACE -
,
SQL- .
SQL_TRACE
SQL_TRACE ,
. , , ,
. , SQL_TRACE
SQL-,
-.
-
ALTER SESSION:
SQL> alter session set sql_trace=true;
, -
. :
SQL> alter session set sql_trace=false;
25
, SQL_TRACE,
. -
, INIT.ORA
. SQLTRACE , -
,
USER_DUMP_DEST. , -
( ) USERDUMPDEST.
, , , -
MTS ,
BACKGROUND_DUMP_DEST. SQLJTRACE -
. -
, , -
, .
:
ora<spid>.trc,
<spid> , -
. Windows
:
SQL> select .value || '\ORA' || to_char (a.spid,'fmOOOOO') || '.trc'
2 from v$process a, v$session b, v$parameter
3 where a.addr = b.paddr
4 and b.audsid = userenv('sessionid')
5 and c.name = 'user_dump_dest';
Unix
:
SQL> select .value II '/' II d.instance_name || '_ora_' ||
2 to_char(a.spid,'fm99999') || '.trc'
3 from v$process a, v$session b, v$parameter c, v$instance d
4 where a.addr = b.paddr
5 and b.audsid = userenv('sessionid')
6 and c.name = 'user_dump_dest';
-
MAX_DUMP_FILE_SIZE, INIT .ORA.
ALTER SESSION,
:
SQL> alter session set max_dump_file_size = unlimited;
Session altered.
TKPROF
TKPROF SQL_TRACE -
. ,
26
.
.
TKPROF
TKPROF ,
. TKPROF
:
tkprof <--> <-->
TKPROF SQL_TRACE, -
. , -
AUTOTRACE,
. SQL*Plus
:
SQL> select .value || '\ORA' || to_char(a.spid,'fmOOOOO') || '.trc'
2 from v$process a, v$session b, v$parameter
3 where a.addr = b.paddr
4 and b.audsid userenv('sessionid')
C.VALUEI!'\ORA'||TO_CHAR(A.SPID,'FMOOOOO')||'.TRC
:\oracle\admin\oratest\udump\ORA01528.trc
Session altered.
SQL> alter session set sql_trace=true;
Session altered.
SQL> exit
-
TKPROF:
C:\oracle\admin\oratest\udump>tkprof ORA01528.TRC tkprof_repl.txt
TKPROF_REPI . .
SQL-.
, .. SQL--
Oracle: (parse, "", "-
". . .), (execute) (fetch).
:
27
> ;
> , ;
> ;
> - ;
> , " "
(consistent-read);
> , "" (current) (, -
-
);
> , .
:
call count cpu elapsed disk query current rows
-
, ( -
ALLJJSERS -
):
Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 52
, , .
1, -
, (bind variables), -
0. -
"" .
, .
AUTOTRACE,
.
Rows Row Source Operation
14 MERGE JOIN
5 SORT JOIN
4 TABLE ACCESS FULL DEPT
14 SORT JOIN
14 TABLE ACCESS FULL EMP
SQL_TRACE TKPROF, -
, 10 Oracle 9i
Database Performance Tuning Guide and Reference.
28
RUNSTATS
RUNSTATS , -
"" ,
(,
) (latches).
( . . .), -
, .
RUNSTATS , , -
Web- h t t p : //asktom.oracle.com. -
RUNSTATS h t t p : / / a s k t o m . o r a c l e . c o m / ~ t k y z e /
r u n s t a t s . html. 4 -
.
-
V$STATNAME, V$MYSTAT V$LATCH. -
SELECT ( ) SYS.V_$STATNAME, SYS.V_$MYSTAT
SYS.V_$LATCH. :
SQL> create or replace view stats
2 as select 'STAT...1 || a.name name, b.value
3 from v$statname a, v$mystat b
4 where a.statistict b.statistic#
5 union all
6 select 'LATCH.' || name, gets
7 from v$latch;
View created.
-
:
create global temporary table run_stats
( runid varchar2(15),
name varchar2 (80),
value int )
on commit preserve rows;
.
create or replace package runstats_pkg
as
procedure rs_start;
procedure rs_middle;
procedure rs_stop( p_difference_threshold in number default 0 );
end;
g_start number;
g_runl number;
g_run2 number;
procedure rs_start
is
begin
delete from run stats;
g start := dbms_utility.get_time;
end;
procedure rs_middle
is
begin
g_runl := (dbms_utility.get_time-g_start);
end;
dbms_output.put_line
1
( 'Runl ran in ' || g_runl || ' hsecs );
dbms_output.put_line
( 'Run2 ran in ' || g_run2 || ' hsecs' );
dbms_output.put_line
( 'run 1 ran in ' || round(g_runl/g_run2*100,2)
1
% of the time' );
dbms output.put_line( chr(9) );
dbms_output.put_line
( rpad( 'Name', 30 ) I I lpad( 'Runl', 10 ) ||
lpad( 'Run2', 10 ) M lpad ( 'Diff, 10 ) );
for x in
( select rpad( a.name, 30 ) | |
to_char( b.value-a.value, '9,999,999'
to chart c.value-b.value, '9,999,999' ||
30
dbms_output.put_line( chr(9) );
dbms_output.put_line
( 'Runl l a t c h e s t o t a l versus runs difference and p e t ' );
dbms_output.put_line
( lpad( 'Runl', 10 ) | | lpad( 'Run2', 10 ) | |
lpad( ' D i f f , 10 ) | | lpad( ' P e t ' , 8 ) ) ;
for x in
( select to_char( runl, '9,999,999' ) ||
to_char( run2, '9,999,999' ) || ..
to_char( diff, '9,999,999' ) ||
to_char( round( runl/run2*100,2 ), '999.99' ) || '%' data
from ( select sum(b.value-a.value) runl, sum(c.value-b.value) run2,
sum( (c.value-b.value)-(b.value-a.value)) diff
from run_stats a, run_stats b, run_stats
where a.name = b.name
and b.name = .name
and a.runid = 'before'
and b.runid = 'after 1'
and c.runid = 'after 2'
and a.name like 'LATCH%'
)
) loop
dbms_output.put_line( x.data );
end loop;
end;
end;
RUNSTATS
,
RUNSTATS, (lookup)
(HEAP) - (). :
31
> ;
> ;
> .
.
SQL> create table HEAP
Table created.
, -
.
Table analyzed.
Table analyzed.
, .
SQL> declare
2 x varchar2(1);
3 begin
4 for i in 1 .. 10000 loop
5 select dummy into x
6 from HEAP;
7 end loop;
8 end;
9/
SQL> declare
2 x varchar2 (1) ;
3 begin
4 for i in 1 10000 loop
5 select dummy into x
6 from IOT;
7 end loop;
32
8 end;
9 /
:
SQL> exec RUNSTATS_PKG.rs_start;
HEAP:
SQL> declare
2 x varchar2(1);
3 begin
4 for i in 1 10000 loop
5 select dummy into x
6 from HEAP;
7 end loop;
8 end;
9/
.
SQL> exec RUNSTATS_PKG.rs_middle
PL/SQL procedure successfully completed.
.
SQL> declare
2 varchar2(1);
3 begin
4 for i in 1 .. 10000 loop
5 select dummy into x
6 from IOT;
7 end loop;
8 end;
9/
-
:
connor@ORATEST> exec RUNSTATS_PKG.rs_stop;
Runl ran in 130 hsecs
Run2 ran in 74 hsecs
run 1 ran in 175.68% of the time
33
i-1
STAT...calls to kcmgas 1 0 -1
STAT...cleanouts and rollbacks 1 0 _^
STAT...immediate (CR) block cl 1 0 -1
STAT...parse time cpu 1 0 -1
<output cropped>...
LATCH.library cache 20,211 20,089 -122
STAT...redo size 2,472 1,740 -732
STAT...table scan blocks gotte 10,000 0 -10,000
STAT...table scan rows gotten 10,000 0 -10,000
STAT...table scans (short tabl 10,000 0 -10,000
STAT...no work - consistent re 10,009 2 -10,007
STAT...buffer is not pinned 10,014 3 -10,011
LATCH.undo global data 40,007 4 -40,003
STAT...calls to get snapshot s 50,011 10,002 -40,009
STAT...consistent gets 50,027 10,012 -40,015
STAT..-db block gets 120,014 18 -119,996
STAT...session logical reads 170,041 10,030 -160,011
LATCH.cache buffers chains 340,125 20 ,113 -320,012
, -
.
,
.
-, -
, .
, Oracle 8.I.7.
Oracle 9/ R2, :
Runl ran in 145 hsecs
Run2 ran in 88 hsecs
run 1 ran in 164.77% of the time
,
- -
- ( ", -
". . .).
2 . 348
34
HEAP
:
create table HEAP ( primary key, padding)
as select rownum r, rpad(rownum,40) padding
from all_objects;
SQL- .
select dummy into x
from [HEAP I IOT] ;
:
select dummy into x
from [HEAP | ]
where r = i;
, .
8.1.7 :
Runl ran in 101 hsecs
Run2 ran in 96 hsecs
run 1 ran in 105.21% of the time
, , - -
-
, HEAP.
HEAP
:
create table HEAP ( primary key, , padding)
as select rownum r, mod(rownum,5000), rpad(rownum,40) padding
from all_objects;
SQL- :
select max(padding) into x
from [HEAP | IOT]
where = i ;
8.1.7 :
Runl ran in 93 hsecs
Run2 ran in 94 hsecs
run 1 ran in 98.94% of the time
,
HEAP . , -
(ROWID),
Oracle ,
.
, , , -
RUNSTATS -
.
^
PL/SQL
PL/SQL. -
"", -
, . ,
" PL/SQL", , , -
PL/SQL .
PL/SQL -
, -
. , PL/SQL
. , -
Oracle, PL/SQL
.
PL/SQL?
PL/SQL, -
, -
: " PL/SQL"?
, 1980-
, - -
, Web, (
Oracle) "" .
, Oracle 7,
--
.
-
, , -
-
.
PL/SQL ( , -
Oracle ).
, , -
, PL/SQL -
. , ,
PL/SQL Oracle -
. , ,
, PL/SQL,
!
38 1
PL/SQL
:
> Oracle;
> " <
^'.
, -
, ,
PL/SQL Oracle -
. , PL/SQL -
,
PL/SQL.
PL/SQL
. PL/SQL
. 4, " ", -
PL/SQL--
.
, 2, " ", PL/SQL
. PL/SQL-
,
.
-
PL/SQL, SQL, ,
, , PL/SQL
. -
-
. , ;
PL/SQL *
.
PL/SQL- ( !):
PROCEDURE insert_blob_proc IS
Blob_loc BLOB;
BEGIN
SELECT ad_photo INTO Blob_loc
FROM Print_media
WHERE product_id = 3106 AND ad_id=13001;
INSERT INTO Print_media VALUES (2056, 12001, Blob_loc);
END;
*:
#include <oci.h>
include <stdio.h>
PL/SQL 39
#include <sqlca.h>
void Sample_Error()
void insertBLOB_proc()
{
OCIBlobLocator *Lob loc;
void main()
{
char *samp = "pm/pm";
EXEC SQL CONNECT :pm;
insertBLOB_j>roc() ;
EXEC SQL ROLLBACK WORK RELEASE;
1
OCI ,
*. , ,
, SQL- -
. ,
, , , . , Java
SQL- S t a t e m e n t P r e p a r e d S t a t e m e n t .
JDBC
Oracle PreparedStatement. (, , -
" " .)
, , -
, statement.
40 1
" PL/SQL"?
(, , ) -
PL/SQL, , ,
PL/SQL-.
,
PL/SQL. , -
, , -
, .. , ,
,
.
,
PL/SQL-.
PL/SQL,
. , -
( ) -
.
( , -
PL/SQL), PL/SQL ,
- .
? , PL/SQL-
,
:
> . ;
> . " " ( -
);
> . ( ), -
. , "", .
. , -
,
. -
.
PL/SQL, , -
", ". ,
, -
? ?
. ,
? -
, Oracle,
PL/SQL, , , -
. -
PL/SQL 41
,
- , .
, ,
. PL/SQL-, ""
( ),
, -
. PL/SQL- -
. , :
> , -
;
> ( , -
..),
;
>
.
PL/SQL- , "" -
, ,
.
, "rev head" (). , -
, , -
.
, . ,
, . , -
? , . ,
7 9 , ,
!
, -
.
, , , -
(, , ) . -
- , -
, .
(demonstrability). -
, : ", ,
. ". -
, . -
:
> , -
;
PL/SQL 43
> , -
, , . (
,
.);
> , "" ,
!
:
, -
, ,
-
( , 4 -
).
() , -
.
, ,
, .
,
-
. , -
PIN- ( -
), .
, .. .
PIN- -
. , -
.
, -
, ,
customers. , , -
.
.
, .
SQL> c r e a t e t a b l e customers (
2 pin_number number(6) )
Table created.
SQL> a l t e r table customers
2 add c o n s t r a i n t customers_pk
3 primary key (pin_number);
Table altered.
customers pin_number,
. -
, , -
dbms_random, customers.
44 1
v_new_cid ,
. customers.
8 insert into customers
9 values (v_new_cid);
10 exit;
, ,
dup_val_on_index. -
.
11 exception when dup_val_on_index then
12 null;
13 end;
14 end loop;
15 end;
16 /
Procedure created.
.
. set timing on SQL*Plus
.
SQL> set timing on
SQL> begin
2 gen_customer;
3 commit;
4 end;
5 /
Elapsed: 00:00:00.02
. -
100000 .
SQL> set timing on
SQL> begin
2 for i in 1 .. 100000 loop
3 gen_customer;
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 45
Elapsed: 00:00:34.08
! 100000 30 , -
, ,
, -
. , ,
, "".
, , -
. , PIN- ,
pin_number , 999999 .
1.1 , -
.
1.1.
100000 200000 38
300000 400000 53
600000 700000 123
: , , -
PIN- , -
PIN-.
-
. -
, . ,
PIN-. (
, PIN-) ,
. , -
, , -
(
).
" ". -
, ,
. , -
. . -
, .
, -
, -
( ),
.
, 6 ,
100000. -
PIN-.
46 1
SQL> alter table CUSTOMERS modify PIN_NUMBER number(12);
Table altered.
Sequence created.
PIN-, -
, .
, .. ,
dup_vai_on_index .
SQL> create or replace
2 procedure gen_customer is
3 v_new_cid customers.pin_number%type;
4 begin
5 insert into customers
6 values (cust_seq.nextval*100000+
7 round(dbms_random.value(100000,999999)));
8 end;
9 /
Procedure created.
, -
( ),
-
, 1.2.
1.2.
0 100000 55
100000 200000 55
300000 400000 59
600000 700000 59
900000 999999 61
, ,
, . , -
. -
, , -
.
dbms_job. , -
PL/SQL ( 10000 ):
PL/SQL 47
begin
for i in 1 .. 10000 loop
gen_customer;
end loop;
commit;
end;
20- ,
20 dbms_job. -
, , 20- :
SQL> a l t e r system set job_queue_processes = 20;
System a l t e r e d .
, -
dbms_output, custlog
.
SQL> c r e a t e table custlog(elapsed_centiseconds number);
Table created.
PL/SQL-
dbms_j ob. , -
custlog.
SQL> declare
2 numl
j number;
3 job_string varchar2(1000) :=
4 'declare
5 s number := dbms_utility.get_time;
6 begin
7 for i in 1 . . 10000 loop
8 gen_customer;
9 end loop;
10 insert into custlog values (dbms_utility.get_time-s);
11 commit;
12 end;;
13 begin
14 for i in 1 .. 20 loop
15 dbms_job.submit(j,job_string);
16 end loop;
17 end;
18 /
, commit. -
-
custlog.
48 1
SQL> select * from custlog;
ELAPSED_CENTISECONDS
10785
10878
11172
11116
11184
11450
11347
11701
11655
11897
11726
12055
11962
12028
12373
11859
11995
11905
12547
11977
20 rows selected.
115 ,
customers 200000 . , -
, -
55-60 , 100000 , -
.
, -
,
. , -
.
PL/SQL, , , -
. .
, PL/SQL .
-
.
> SQL-, -
. , PL/SQL,
SQL- PL/SQL--
. SQL- -
PL/SQL 49
, PL/SQL, -
-
. , , -
!
, , -
PL/SQL, , -
.
Oracle
, Oracle
SQL-.
EXPLAIN PLAN, , SQL-
, , -
; SQL- ,
. , Oracle -
. ,
PL/SQL. , Oracle ( -
), -
Java/JDBC Visual Basic/ODBC,
SQL- , .
, (, , ),
.
, .
; , -
Oracle SQL- .
;
SQL, , -
, , , -
. SQL-, ,
. ,
SQL- . SQL-
,
.
, SQL-, , -
, . SQL-
, -
SQL-,
.
50 1
-
,
SQL-.
Oracle :
. SQL-
(parsing), , -
. SQL-, ,
, . -
SQL- ,
.
Oracle SQL-, -
(hard parse, " "), .. -
SQL-. Oracle SQL- -
, ,
(soft parse, " ").
SQL- , -
.
SQL-, -
, (bind
variables). -
SQL- -. , -
-
( SQL- ), ,
SQL- .
? ,
- -
, Oracle SQL- ,
. SQL-,
, -
, .
, -
.
dbms_sqi, -
SQL-1. people ,
.
SQL> create table people( pid primary key )
2 organization index
3 as s e l e c t rownum from all_objects
4 where rownum <= 10000;
Table created.
' OakTable, , .
PL/SQL 51
, , ,
.
:
select pid from people where pid 123;
select pid from people where pid = 124;
-etc....
SQL- SQL- -
. 10000 person, -
.
SQL> create or replace
2 procedure literals is
3 number;
4 p number;
5 x number;
6 xl number;
7 begin
8 for i in 1 .. 10000 loop
dbms_sql
open_cursor , . -
parse.
. -
close.
9 := dbms_sql.open_cursor;
10 dbms_sql.parse(,
11 'select pid from people '||
12 'where pid = 'I|i, dbms_sql.native);
13 x := dbms_sql.execute(c) ;
14 xl := dbms_sql.fetch_rows(c);
15 dbms_sql.close_cursor(c);
16 end loop;
17 end;
18 /
Procedure created.
SQL*Plus
, , -
, .
sqi_trace.
SQL> set timing on
SQL> alter session set sql_trace = true;
Session altered.
SQL> exec literals;
PL/SQL procedure successfully completed.
52 1
Elapsed: 00:00:29.68
SQL> alter session set sql_trace = false;
Session altered.
. , 10000
2
30 . Tkprof -
.
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
, -
people ,
literals.
100000 2,49 -
(.. 1,63 + 0,86), , -
26,96 10 -
, ! (, , )
, SQL-
, . , -
, , (28,19
29,45 ).
, . ,
. , -
l i t e r a l s -
. -
, .
l i t e r a l s . tag
SQL-,
SQL-.
SQL> create or replace
2 procedure literals(tag number) is
3 number;
4 p number;
5 x number;
6 xl number;
2
Tkprof 10 Performance Tuning Guide and Reference -
Oracle.
PL/SQL 53
7 begin
8 for i in 1 .. 10000 loop
9 := dbms_sql.open_cursor;
10 dbms_sql.parse(c,
11 'select pid t 1 | I tag I |' from people '| |
12 'where pid = '||i, dbms_sql.native);
13 x := dbms_sql.execute(c);
14 xl := dbms_sql.fetch_rows(c);
15 dbms_sql.close_cursor(c);
16 end loop;
17 end;
18 /
l i t e r a l s (1) , l i t e r a l s (2)
.. (, -
, ):
SQL> exec literals(1);
Elapsed: 00:00:31.70
SQL> exec literals(2);
Elapsed: 00:00:32.05
SQL> exec literals (3);
Elapsed: 00:00:31.43
SQL> exec literals(4);
Elapsed: 00:00:32.21
? l i t e r a l s ,
29,68 . 4 , -
, 30 . -
. , , -
V$SESSION_EVENT
.
. Yet Another Performance Profiling Method (Anjo
Kolk), (Shari Yamaguchi) (Jim Viscusi)
oraperf.veritas.com.
, , -
. ,
. :
SQL> select sid, event, time_waited
2 from v$session_event
3 where sid = ...
4 and event = 'latch free';
SID ,
. , :
54 1
43 latch free 79
44 latch free 72
45 latch free 69
46 latch free 87
Oracle , -
, ,
, -
. , 0,8 (3 )
latch free, ..
, SQL-.
Oracle 9.2, ,
(SID) . -
, , SID=42
V$SESSION, V$SESSION_EVENT SID=41.
10 9.2.0.4.
, -
, , . -
.
, . -
, SQL- -
SQL-. -
. l i t e r a l s , , binding,
.
SQL> create or replace
2 procedure binding is
3 number;
4 p number;
5 x number;
6 xl number;
7 begin
8 for i in 1 .. 10000 loop
9 := dbms_sql.open_cursor;
10 dbms_sql.parse(c,
11 'select pid from people '||
12 'where pid = :bl', dbms_sql.native);
, SQL- -
. .
, 10000
PL/SQL 55
SQL-. , -
Oracle.
13 dbms_sql.bind_variable(,':',i);
14 := dbms_sql.execute();
15 xl := dbms_sql.fetch_rows();
16 dbms_sql.close_cursor();
17 end loop;
18 end;
19 /
Procedure created.
,
.
SQL> alter session set sql_trace = true;
Session altered.
,
( --
10000), - -
.
select pid
from
people where pid = :bl
, - . -
, dbms_sql.parse 10000 , -
. , -
,
. , -
.
SQL> create or replace
2 view V$MYSTATS as
56 1
, -
.
SQL> select * from v$mystats
2 where name like 'parse%';
NAME VALUE
. parse
.
12 for i in 1 .. 10000 loop
13 dbms_sql.bind_variable(,':bl',i);
14 x : = dbms_sql.execute();
15 xl := dbms_sql.fetch_rows(c);
16 end loop;
17 dbms_sql.close_cursor(c);
18 end;
19 /
Procedure created.
-
.
select pid
from
people where pid = :bl
.
30 1 .
, ,
Oracle 10000 SQL- .
SQL- -
dbms_sql. PL/SQL -
.
SQL.
SQL> create or replace
2 procedure EASY_AS_THAT is
3 xl number;
4 begin
5 for i in 1 .. 10000 loop
6 select pid into xl
7 from people
8 where pid = i;
9 end loop;
10 end;
11 /
Procedure created.
58 1
,
() . PL/SQL
PL/SQL
SQL-. Oracle
PL/SQL -
. , -
PL/SQL . -
Oracle.
Oracle PL/SQL, , ,
,
. -
. -
Java
JDBC- statement PreparedStatement.
JDBC SQL-
statement. , -
, , :
Statement stmt = conn.createStatement();
for (int i = 0; i < 10000; i++) {
ResultSet rs = stmt.executeQuery("select pid from people where pid =" + i ) ;
stmt. close {) ;
}
, . -
PreparedStatement -
:
PreparedStatement ps;
for (int i = 0; i < 10000; i++) {
pstmt = conn.prepareStatement ("select pid from people where pid ?" ) ;
pstmt.setlnt(1, i) ;
ResultSet rs = pstmt.executeQuery();
pstmt.closed ;
)
)
, -
. . -
, . pstmt,
SQL- . , -
SQL-
, . Java -
singleton, .
static PreparedStatement pstmt;
if (pstmt == null) (
pstmt = conn.prepareStatement ("select pid from people where pid = ?" ) ;
PL/SQL 59
PL/SQL
PL/SQL, : " !". -
: " , -
, ,
".
PL/SQL Oracle -
PL/SQL,
. 2, " -
", Oracle,
,
.
update_emp.
. -
SQL-.
SQL> create or replace
2 procedure UPDATE_EMP(p_empno number, p_decrease number) is
3 begin
4 update EMP
5 set SAL SAL / p_decrease
6 where empno = p_empno;
7 end ;
8 /
Procedure created.
7379 ,
:
60 1
He , ,
0 -
p_decrease.
SQL> exec UPDATE_EMP(7369,0);
BEGIN UPDATE_EMP(7369,0); END;
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at "UPDATE_EMP", line 3
ORA-06512: at line 1
,
, . PL/SQL -
, : -
,
. - -
,
, , PL/SQL-
. , update_emp , -
, , -
.
p_decrease , .
SQL> create or replace
2 procedure UPDATE_EMP(p_empno number, p_decrease number,
3 p_success out boolean) is
4 begin
5 if p_decrease = 0 then
6 p_success := false;
7 else
8 update EMP
9 set SAL = SAL / p_decrease
10 where empno = p_empno;
11 p_success := true;
12 end if;
13 end;
14 /
Procedure created.
, PL/SQL-, -
. -
( 4, "
", -
PL/SQL).
PL/SQL 61
PL/SQL -
, . ( , -
: " ", .) ,
, , -
, PL/SQL-, -
. , .. ,
.
SQL> create or replace
2 function binary_and(x number, number) return number is
3 max_bin number(22) := power(2,64);
4 l_x number := x;
5 l_y number := y;
6 result number := 0;
7 begin
8 for i in reverse 0 .. 64 loop
9 if l_x >= max_bin and l_y >= max_bin then
10 result := result + max_bin;
11 end if;
12 if l_x >= max_bin then
13 l_x := l_x - max_bin;
14 end if;
15 if l_y >= max_bin then
16 l_y := l'_y - max_bin;
17 end if;
18 max_bin : = max_bin/2;
19 end loop;
20 return result;
21 end;
22 /
Function created.
, ,
BITAND. BITAND Oracle 7 (,
, ), Oracle
8.1.7. -
. 50000 "" BITAND
PL/SQL
SQL*Plus .
SQL> declare
2 x number;
3 begin
4 for i in 1 .. 50000 loop
5 x:= binary and(i,i+l);
6 end loop;
7 end;
8 /
62 1
PL/SQL procedure successfully completed.
Elapsed: 00:00:07.07
SQL> declare
2 x number;
begin
for i in 1 .. 50000 loop
x:= bitand(i,i+1);
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
SQL , -
. , -
, ,
, ,
.
"", -
. ,
. src, -
1 9999. ( src , -
.)
SQL> create table SRC ( x number ) pctfree 0;
Table created.
SQL> insert into SRC
2 select rownum
3 from all_objects
4 where rownum < 10000;
ALL_OBJECTS Tl -
created , .
SQL> create table Tl as
2 select trunc(created) created
3 from all_objects;
Table created.
src, , -
,
. .
PL/SQL 63
30//03 0
31//03 0
01/JUN/03 0
02/JUN/03 0
03/JUN/03 0
04/JUN/03 0
05/JUN/03 0
06/JUN/03 0
07/JUN/03 0
08/JUN/03 0
09/JUN/03 41
10/JUN/03 4
ll/JUN/03 6
12/JUN/03 8
, PL/SQL,
, .
src. -
(pipeline functions), 9, , ,
. (-
. 53," PL/SQL".)
( -
).
SQL> create or replace
2 type date_list is table of date;
3 /
Type created.
,
( p_start_date) ( -
p_limit ).
SQL> create or replace
2 function pipe_date(p_start date, p_limit number)
3 return date_list pipelined is
4 begin
5 for i in 0 . . p_llmit-l loop
6 pipe row (p_start + i) ;
3
src, -
8 ( ).
64 1
7 end loop;
8 return;
9 end;
10 /
Function created.
src ,
PIPE_DATE, .
14 . :
SQL> select column_value, count(created) no_of_obj
2 from tl, table(pipe_date(trunc(sysdate) -14,14) )
3 where column_value = tl.created(+)
4 group by column_value
5 /
COLUMN VA NO OF OBJ
29/MAY/03 0
30/MAY/03 0
31/MAY/03 0
01/JUN/03 0
02/JUN/03 0
03/JUN/03 0
04/JUN/03 0
05/JUN/03 0
06/JUN/03 . 0
07/JUN/03 0
08/JUN/03 0
09/JUN/03 41
10/JUN/03 4
ll/JUN/03 6
, ,
. CARDINALITY, -
Oracle .
, 14 .
SQL> select /*+CARDINALITY(t 14)*/ column_value, count(created) no_of_obj
2 from tl, table(pipe_date(trunc(sysdate)-14,14)) t
3 where column_value = tl.created(+)
4 group by column_value
5 /
He PL/SQL SQL
PL/SQL . -
"PL/SQL User's Guide and Reference", Oracle 9.2,
: " PL/SQL, SQL Oracle...". PL/SQL -
SQL ( ), .. , -
, SQL.
PL/SQL 65
, -
PL/SQL. "" emp dept
,
.
SQL> drop table EMP;
Table dropped.
SQL> drop table DEPT;
Table dropped.
. -
empno deptno .
SQL> alter table EMP add constraint EMP_PK
2 primary key (EMPNO);
Table altered.
Table altered.
src , 200000
. -
. ,
, , 200000. -
, .
9 ,
.
Table created.
SQL> begin
2 for i in 1 .. 200000 loop
3 . 348
66 1
3 insert into SRC values ('x');
4 end loop;
5 end;
6 /
SQL> commit;
Commit complete.
emp 500 ,
rownum, -
( 1 10) dbms_random.
SQL> insert into EMP
2 select rownum,
3 ' Name'I|rownum,
4 sysdate+rownum/100,
5 dbms_random.value(7500,10000) ,
6 dbms_random.value(1,10)
7 from SRC
8 where rownum <= 500;
500 rows c r e a t e d .
dept, 10
deptno 1 10.
SQL> insert into DEPT
2 select rownum, 'Dept'I Irownum
3 from SRC
4 where rownum <- 10;
10 rows created.
500 10 .
, -
.
( , !)
, -
. -
.
report_sai_adjustment, 3- , -
emp
:
> ;
> 20 , -
emp_sai_iog , -
PL/SQL 67
, , , -
;
> , , -
m i n s a l emp_sal_log Y, , N.
,
, . ,
.
, -
, -
. , -
. -,
emp_sai_iog, .
SQL> create table EMP_SAL_LOG (
2 ENAME VARCHAR2(20) ,
3 HIREDATE DATE,
4 SAL NUMBER ( 7 , 2 ) ,
5 DNAME VARCHAR2(20),
6 MIN_SAL VARCHAR2(1) );
Table created.
PL/SQL-,
. ,
.
SQL> create or replace
2 procedure report_sal_adjustment is
-, , -
.
3 v_avg_dept_sal emp.sal%type;
4 v_min_dept_sal emp.sal%type;
5 v_dname dept.dname%type;
-, , -
emp.
6 cursor c_emp_list is
7 select empno, ename, deptno, sal, hiredate
8 from emp;
9 begin
, -
. , ,
( 1 ).
10 for each_emp in c_emp_list loop
11 select avg(sal)
12 into v avg dept sal
_ _ _
68 1
13 from emp
14 where deptno = each_emp.deptno;
. -
20 , -
emp_sal_log ( 2 ). ,
, , -
3
.
15 if abs(each_emp.sal - v_avg_dept_sal ) / v_avg_dept_sal > 0.20 then
16 select dept.dname, min(emp.sal)
17 into v_dname, v_min_dept_sal
18 from dept, emp
19 where dept.deptno = each_emp.deptno
20 and emp.deptno = dept.deptno
21 group by dname;
emp_sai_iog, , -
. -
, -
min_sal emp_sal_log.
22 if v_min_dept_sal = each_emp.sal then
23 insert into emp_sal_log
24 values ( each_emp.ename, each_emp.hiredate,
25 each_emp.sal, v_dname, ' Y ' ) ;
26 else
27 insert into emp_sal_log
28 values ( each_emp.ename, each_emp.hiredate,
29 each_emp.sal, v_dname, ' N ' ) ;
30 end if;
31 end if;
32 end loop;
33 end;
34 /
Procedure created.
( ) , -
, . -
(.. 500
10 ) .
Elapsed: 00:00:00.03
! 3 ( -
), !
PL/SQL 69
, -
. -
? ( , )
. -
( , -
), SQL*Plus -
.
.
rem REPTEST.SQL
rem
rem :
rem , ,
rem
rem
rem 7500 10000.
set termout off
rem ,
rem .
rem SQL Plus
rem NUM_EMPS NUMJDEPTS .
rem DUAL.
rem
rem DEPT, .
rem ,
rem , SRC
rem .
rem DEPT,
rem .
70 1
rem
rem , ,
rem , .
rem , .
truncate table EMP_SAL_LOG;
rem , , .
rem 3
rem 3- .
rem DBMS_OTILITY.GETJTIME,
rem .
rem ( ).
rem 100 3, .
set serverout on
set termout on
declare
x number : = dbms_utility.get_time;
begin
for i in 1 .. 3 loop
report_sal_adjustment;
end loop;
dbms_output.put_line('Average run time: '|l
round((dbms_utility.get_time-x)/3/100,2) ) ;
end;
/
. -
:
SQL> @c:\reptest 500 50
Average run time: .3
, ,
. ,
. , 3 , -
, -
1900 . -
, 3 .
, , -
-
. .
, .
, -
emp, , , . -
, -
.
SQL> create or replace
2 procedure report_sal_adjustment2 is
3 v_avg_dept_sal emp.sal%type;
4 v_min_dept_sal emp.sal%type;
5 v_dname dept.dname%type;
6 cursor c_emp_list is
7 select empno, ename, deptno, sal, hiredate
8 from emp;
9 begin
10 for each_emp in c_emp_list loop
, -
.
11 select avg(emp.sal), min(emp.sal), dept.dname
12 into v_avg_dept_sal, v_min_dept_sal, v_dname
13 from dept, emp
14 where dept.deptno each_emp.deptno
15 and emp.deptno = dept.deptno
16 group by dname;
72 1
.
17 if abs(each_emp.sal - v_avg_dept_sal ) / v_avg_dept_sal > 0.20 then
18 if v_min_dept_sal = each_emp.sal then
19 insert into emp_sal_log
20 values ( each_emp.ename, each_emp.hiredate,
21 each_emp.sal, v_dname, ' Y ' ) ;
22 else
23 insert into emp_sal_log
24 values ( each_emp.ename, each_emp.hiredate,
25 each_emp.sal, v_dname, ' N ' ) ;
26 end if;
27 end if;
28 end loop;
29 end;
30 /
Procedure created.
REPTEST.SQL , -
report_sai_adjustment2.
, 1.3.
1.3. REPORT_SAL_ADJUSTMENT
500 50 0,27
1000 100 0,86
1500 150 1,68
2000 200 3,03
2500 250 4,64
, 10 .
. , -
50000 ?
,
. , SQL--
emp, , , .
,
, SQL- -
.
PL/SQL, ,
. , -
:
SQL> create or replace
2 procedure report_sal_adjustment3 is
( -
) , , , -
. :
, .
PL/SQL 73
.
PL/SQL-.
13 cursor c_dept_salaries is
14 select avg(sal) asal, min(sal) msal, dname, dept.deptno
15 from dept, emp
16 where emp.deptno dept.deptno
17 group by dname, dept.deptno;
18 begin
PL/SQL-.
deptno , -
PL/SQL-.
19 for i in c_dept_salaries loop
20 v_dept_sal(i.deptno).avg_dept_sal := i.asal;
21 v_dept_sal(i.deptno).min_dept_sal := i.msal;
22 v_dept_sal(i.deptno).dname : = i.dname;
23 end loop;
24 for each_emp in c_emp_list loop
dept.
PL/SQL-
(v_dept_sal).
Procedure created.
74 1
, "-
" dept emp. -
, REPTEST . SQL
( report_sal_adjustment3).
1.4.
REPORT_SAL_ADJUSTMENT
500 50 0,03
1000 100 0,05
5000 500 0,24
25000 2500 1,24
50000 5000 2,74
. , -
, , , .
. , , -
. , -
,
V$MYSTAT. 5000
, .
SQL> col value format 999,999,999
SQL> select * from v$mystats
2 where name = 'session pga memory max'
3 /
NAME VALUE
4 . -
, 50000 , -
. ... .
,
. ,
.
PL/SQL, PL/SQL ! SQL -
. (, -
Oracle 9. 8, -
i n s e r t SQL, .. EXECUTE
IMMEDIATE.)
SQL> c r e a t e or replace
2 procedure report_sal_adjustment4 i s
3 begin
4 insert into emp_sal_log
5 select e.empno, e.hiredate, e.sal, dept.dname,
PL/SQL 75
Procedure created.
! SQL-. PL/SQL-
, SQL-. -
REPTEST . SQL -
, 1.5.
1.5. REPORT_SAL_ADJUSTMENT
500 50 0,01
5000 500 0,08
50000 5000 0,83
100000 10000 1,71
,
report_sal_adjustment4, , -
Oracle. ,
8.1.6, -
. , ,
, -
-
. Data Warehousing ( -
Oracle). ,
, , .
!
.
Oracle SQL-.
, ( ) , -
SQL, PL/SQL. , -
, ( ,
76 1
). ,
PL/SQL, :
" V X, Y Z.
X V, ( )".
PL/SQL , ,
", , ". -
-, 7.1, -
Oracle, ,
. Oracle -
(DBAJJPDATABLE_COLUMNS), , -
DML.
.
10 , -
YEARLY_BONUS.
create or replace view YEARLY_BONUS as
select emp.empno, emp.ename, dept.dname, emp.bonus
from EMP, DEPT
where emp.hiredate < sysdate + 1
and emp.deptno = dept.deptno
PL/SQL, , -
, .
create or replace
procedure XXX is
begin
for i in ( select empno from yearly_bonus ) loop
update emp
set bonus = bonus * 1.1
where empno = I.empno;
end;
/
:
update yearly_bonus set bonus = bonus * 1.1;
PL/SQL-, .
, ! , ,
. :
update ( s e l e c t emp.ename, dept.dname, emp.bonus
from EMP, DEPT
where emp.hiredate < sysdate + 1
and emp.deptno = dept.deptno)
set bonus bonus * 1.1;
, -
(. "Modify a Join View" "Application Developer Funda-
mentals"), PL/SQL .
PL/SQL 77
SQL PL/SQL
SQL PL/SQL ,
SQL, PL/SQL -
. , SQL, -
. , , -
SQL PL/SQL, ,
, SQL PL/SQL. -
, SQL.
PL/SQL DBMS_OUTPUT . PUT_LINE
( )
, SQL, -
. ,
decode, -
SQL. mdate
, .
SQL> col dte new_value mdate
SQL> select '23-JUN-03' dte from dual;
DTE
23-JUN-03
SQL-
. src, -
, -
.
SQL> select
2 max(decode(dow,1,d,null)) Sun,
3 max(decode(dow,2,d,null)) Mon,
4 max(decode(dow,3,d,null)) Tue,
5 max(decode(dow,4,d,null)) Wed,
6 max(decode(dow,5,d,null)) Thu,
7 max(decode(dow,6,d,null)) Fri,
8 max(decode(dow,7,d,null)) Sat
9 from
10 ( select rownum d,
11 rownum-2+to_number(
12 to_char(trunc(
13 to_date('Smdate'),'MM'),'D')) p,
14 to_char(trunc(to_date('smdate'),'MM')
15 -1+rownum,'D') dow
16 from SRC
17 where rownum <= to_number(to_char(
18 last_day (to" date (' smdate ') ) ,' DD') ) )
78 1
19 group by trunc(p/7)
20 /
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
6 rows selected.
SQL- , -
.
-
, ,
,
, . -
:
> ();
> , , -
[n/2+l] ;
> , , -
[/2];
> .
-
,
( 9).
SQL> select percentile_cont(0.5)
2 within group (order by sal desc ) median_sal
3 from emp;
MEDIAN SAL
!___
1550
: -
SQL PL/SQL , ,
emp. 1000000 emp, -
PL/SQL-: , -
, PERCENTILE_CONT.
SQL> set timing on
SQL> exec median_using_old_method
PL/SQL 79
6044.5
-
.
( ) -
, ,
. -
.
, :
> , , -
FIXED_PRICE part_time_package;
> , , -
HRS HRLY_RATE contract_package;
> ANNUALSAL
BONUS perm_package.
staff class_type , -
, . -
, . -
emp dept .
SQL> @$ORACLE_HOME/sqlplus/demo/demobld.sql
Building demonstration t a b l e s . Please wait.
Demonstration t a b l e b u i l d i s complete.
, -
.
SQL> create table STAFF (
2 staffno number,
3 name varchar2(30) ,
4 class_type number,
5 class id number);
Table created.
Table created.
Table created.
, -
src.
SQL> insert into part_time_package
2 select rownum, rownum*130
3 from SRC where rownum < 6;
5 rows created.
5 rows created.
5 rows created.
14 rows created.
, PL/SQL, ,
, .
PL/SQL,
, , -
CLASSJTYPE.
SQL> create or replace
2 procedure SHOW_SAL is
v
3 _ s a l number;
4 begin
5 for i in ( select * from staff ) loop
PL/SQL 81
7 ,
8 PART TIME PACKAGE
10 if i.class_type = 1 then
11 select fixed_price
12 into v_sal
13 from part_time_package
14 where id = i.class_id;
15
16
17 CONTRACT_PACKAGE
18
19 elsif i.class_type = 2 then
20 select hrs * hrly_rate
21 into v_sal
22 from contract_package
23 where id = i.class_id;
24
25
26 PERM_PACKAGE
27
28 elsif i.class_type = 3 then
29 select annual_sal + bonus
30 into v_sal
31 from perm_package
32 where id = i . c l a s s _ i d ;
33 end if;
34 dbms__output.put_line (rpad (i.name,20) | | l p a d ( v _ s a l , 1 0 ) ) ;
35 end loop;
36 end;
37 /
Procedure created.
,
.
SQL> exec show_sal;
ALLEN 1200
WARD 31500
MARTIN 520
BLAKE 7500
CLARK 10500
SCOTT 260
KING 2700
TURNER 42000
ADAMS 650
JAMES 300
FORD 21000
MILLER 390
SQL-
, PL/SQL-, -
CASE , 8/.
SQL> s e l e c t s.name,
2 case class type
3 when 1 then (
4 select fixed price
5 from part time package
6 where id = s.class id )
7 when 2 then (
8 select hrs * hrly rate
9 from contract package
10 where id = s.class id )
11 when 3 then (
12 select annual sal + bonus
13 from perm package
14 where id = s.class id )
15 end sal
16 from staff s;
NAME SAL
ALLEN 1200
WARD 31500
MARTIN 520
BLAKE 7500
CLARK 10500
SCOTT 260
KING 2700
TURNER 42000
ADAMS 650
JAMES 300
FORD 21000
MILLER 390
Oracle lOg
-
SQL 10g.
, SQL. , -
, MODEL, -
SQL-.
, -
MODEL,
,
.
SQLSQL> create table SAMPLES (
2 lab_id varchar2(10) ,
3 animal varchar2(10) ,
PL/SQL 83
4 experimented number,
5 probability number );
Table created.
, , , ,
? -
1, 2 3. Oracle ^
MODEL.
SQL> SELECT lab__id, animal, experimented,
2 FROM samples
3 SPREADSHEET PARTITION BY (lab_id)
4 DIMENSION BY (animal, experiment_id)
5 MEASURES (probability s) IGNORE nav
6 (s ['MICE', -l]=s['MICE',l]*s[ 'MICE',2]*s['MICE' ,3]
7 s ['RATS',-l]=s['RATS',l]*s[ 'RATS',2]*s['RATS' ,3]
16 rows selected.
84 1
-1 .
MODEL Oracle 10g -
(
), ,
PL/SQL , SQL-.
PL/SQL-?
SQL,
PL/SQL? , , , -
. SQL -
, PL/SQL, " ". SQL-
- ,
. ( "", -
.) , ,
, PL/SQL -
,
. SQL-
PL/SQL. ,
PL/SQL -
.
PL/SQL SQL. -
( )
. (resumable
transaction), 9, ( ) -
.
. PL/SQL-, -
SQL
Oracle, PL/SQL-. SQL- -
,
PL/SQL. , ( ) PL/SQL -
SQL, .
, PL/SQL-
. , , PL/SQL
.
PL/SQL , -
. , -
PL/SQL , -
, , PL/SQL,
.
PL/SQL 85
PL/SQL , -
. -
PL/SQL-
, . ,
, -
-
. -
, ,
, PL/SQL
, ,
PL/SQL-.
2
-
. "", "", "-
" "" -
. PL/SQL, Ada,
, , -
; -
.
, (
, ), ,
-
. , -
, ,
. , -
Oracle, , :
,
.
,
. , -
PL/SQL, ,
. , -
Oracle , -
PL/SQL-. "" ,
, :
create or replace
package emp_maint is
procedure hire_emp (p_empno number, p__name varchar2) ;
procedure fire_emp(p_empno);
procedure raise_salary(p_empno number, p_salary number);
end;
/
.
create or replace
package body emp_maint is
88 2
procedure fire_emp(p_empno) is
begin
delete from emp ...
end;
1. -
,
. .
create or replace
package emp maint is
cursor annual review candidates return emp%rowtype;
v_last_empno_used number;
procedure hire_emp(p_empno number, p_name varchar2);
procedure fire_emp(p_empno number);
procedure raise_salary(p_empno number, p_salary number);
procedure hire_emp (p_empno number, p_name varchar2,
p_hiredate date, p_sal number);
end;
/
create or replace
package body emp_maint is
' Oracle, , -
. . " , " .
89
end;
begin
select empno into v_last_empno_used
from EMP
where hiredate = ( select max(hiredate)
from emp )
and rownum = 1;
end;
/
, ,
.
, empmain -
hire_emp.
.
procedure hire_emp(p_empno number, p_name varchar2,
p_hiredate date, p_sal number);
, . -
, hire_emp
.
,
, -
.
procedure hire_emp(p_empno number, p_name varchar2,
p_hiredate date default null, p_sal number default null) ;
90 2
,
p_hiredate p_sal, .
. -
-
. , -
hire_emp ( " " "
"). , -
( "
" ""). -
hire_emp , , .
-
, - -
.
emp_maint :
v_last_empnio_used number;
:
v_pkg_execution_count number : = 0;
. , (-
, create package), .
.
, , ,
.
, emp maint, -
1000 v_iast_empno,
.
, "-
", .
, -
s e r i a l l y _ r e u s a b l e .
, -
. , ,
. -
. , -
91
.
-
, , , -
, ..
, , PL/SQL-.
.
create or replace
package body emp_maint is
begin
select empno into v_last_empno_used
from EMP
where hiredate = ( select max(hiredate)
from emp )
and rownum = 1;
end;
-
. emp_maint
v_last_empno, . -
, -
.
. .
emp_maint .
check_sal_limit.
procedure check_sal_limit(p_empno number) i s
begin
end;
, check_sai_limit
, ,
. , ,
-,
hire_emp, .
check_sal_limit ,
. -
.
92 2
, annual_review_candidates , -
,
. , -
.
cursor annual_review_candidates return emp%rowtype;
.
cursor annual_review_candidates return emp%rowtype is
select * from emp where hiredate > trunc(sysdate, 'YYYY');
(.. -
) , -
, .
emp_maint. , -
, , -
.
procedure process_annual_review is
begin
for i in emp_maint.annual_review_candidates loop
()
end_loop;
end;
, .
, PL/SQL -
. , , Oracle
. 3, -
, PL/SQL-
.
, -
. -
.. " ".
Oracle ( ) -
.
Oracle USER_DEPENDENCIES -
:
SQL> desc user_dependencies
Name
NAME
TYPE
REFERENCED OWNER
93
REFERENCED_NAME
REFERENCED_TYPE
REFERENCED_LINK_NAME
SCHEMAID
DEPENDENCY_TYPE
, emp_maint
:
SQL> select name, type,
2 referenced_name, referenced_type
3 from user_dependencies
4 where name = 'EMP_MAINT'
5 /
8 rows selected.
, -
:
> emp_maint standard (
PL/SQL);
> emp_maint standard;
> empmaint emp (
annual_review_candidates);
> empmaint emp ( , -
, );
> emp_maint .
, USER_DEPENDENCIES -
-,
. Oracle
CONNECT BY, , -
.
CONNECT BY
USERDEPENDENCIES, -
CONNECT BY, Oracle 9 -
, CONNECT BY
94 2
. 9 -
USER_DEPENDENCIES, , - -
. ,
$ORACLE_HOME/rdbms/admin/utldtree. sql -
. , -
emp MCDONAC , :
DEPENDENCIES
TABLE MCDONAC.EMP
PACKAGE BODY MCDONAC.PKG1
PROCEDURE MCDONAC.PI
PROCEDURE MCDONAC.P2
PROCEDURE MCDONAC.P3
PROCEDURE MCDONAC.P4
TRIGGER MCDONAC.EMP DEPT CNT TRIGGER
, ,
. 1, -
emp.
SQL> create or replace
2 procedure PI is
3 v_cnt number;
4 begin
5 select count(*)
6 into v_cnt
7 from emp;
8 end;
9 /
Procedure created.
: 2, 4.
.
SQL> create or replace
2 procedure P2 is
3 begin
4 PI;
5 end;
6 /
Procedure created.
95
Procedure created.
Procedure created.
USERDEPENDENCIES.
SQL> select name, type,
2 referenced_name, referenced_type
3 from user_dependencies
4 /
: P I emp
STANDARD ( PL/SQL). 2 P I ,
2, 4 . , -
-
( , , ). -
, P I ,
.
VALID, USERJDBJECTS.
SQL> select object_name, status
2 from user_objects
3 where object_name in ('PI','P2','P3','P4');
P4 VALID
P3 VALID
P2 VALID
PI VALID
96 2
, pi.
SQL- , -
.
SQL> create or replace
2 procedure PI is
3 v cnt number;
4 begin
5 select count(*)
6 into v cnt
7 from emp
where enpno > 0;
9 end;
10 /
Procedure created.
USER_OBJECTS, -
.
SQL> select object_name, status
2 from user_objects
3 where object_name in ('PI','P2','P3','P4');
P4 INVALID
P3 INVALID
P2 INVALID
PI VALID
P I ( ,
), , 1, -
. Oracle
. , ,
.
SQL> exec ;
-
.
SQL> select object_name, status
2 from user_objects
3 where object_name in ('PI,'P2','P3','P4');
OBJECT_NAME STATUS
P4 INVALID
P3 VALID
P2 VALID
PI VALID
97
, 2 , -
. 4 ,
.
, , 4
: , ? -
, ,
, .
, -
u s e r o b j e c t s , -
.
uti_recomp ( 10g), -
.
,
, ,
PL/SQL. ,
, PL/SQL-. -
, ,
standard, .
SQL> create or replace
2 procedure pO is
3 begin
4 null;
5 end;
6 /
Procedure created.
100 ,
PL/SQL- PL/SQL-
. 50 _0001 _0050,
.
SQL> declare
2 varchar2(32767);
3 varchar2(32767);
4 begin
5 for i in 1 . . 50 loop
6 execute immediate
7 'create or replace procedure prc_'I |to_char(i,'fmOOOO') I I
8 ' is begin pO; end;';
50 _0051 _.
prcOOOl _0050, .
9 :- I I 'prc_'Ilto_char(i,'fmOOOO') ||'; ';
10 end loop;
11 for i in 51 .. 100 loop
12 execute immediate
4 . 348
98 2
, , prcmain,
50 _0051 _0100.
15 := II '_'|Ito_char(i,'fmOOOO')I ; ';
16 end loop;
17 execute immediate
18 'create or replace procedure prc_main '||
19 ' is begin 'IlylI' end;';
20 end;
21 /
102 , -
.
SQL> select name, type,
2 referenced_name, referenced_type
3 from user_Dependencies
4 where name like 'PRC '
,
. -
.
SQL> create or replace
2 procedure P0 is
3 x number;
4 begin
5 x := 1;
6 end;
7 /
Procedure created.
,
.
SQL> select object_name, status
2 from user_Objects
3 where object_name like 'PRC%'
4 /
99
PRC0001 INVALID
PRC0002 INVALID
PRC0003 INVALID
...
PRC_MAIN INVALID
PL/SQL : ,
Oracle , .
, . -
-
, prc_main
. -
V$MYSTATS2 -
. ,
. xl.
SQL> create table xl as select * from v$mystats;
Table created.
prc_main. -
_ .
SQL> exec prc_main;
2.
SQL> create table x2 as select * from v$mystats;
Table created.
prc_main. (
prc_main) ,
.
SQL> exec prc_main;
2
V$MYSTATS . 1.
100 2
SQL> create table as select * from v$mystats;
Table created.
2 xl
prcjmain ,
2
( ). SQL--
, , -
.
SQL> select x2.name, .value-x2.value NORMAL_RUN,
2 x2.value-xl.value WITH RECOMP
3 from xl, x2, x3
4 where x2.name = xl.name
5 and x3.name m x2.name
6 order by 3;
( )
NORMAL_RUN WITH_RECOMP
NAME
1 103
2 103
parse count (hard)
5 207
sorts (memory) 2 1394
workarea executions - optimal 3 1401
recursive cpu usage 1 1439
CPU used by this session 1 1476
parse time cpu 20 1535
parse time elapsed 17 1635
opened cursors cumulative 17 1635
enqueue releases
18 5068
enqueue requests
19 5284
parse count (total)
22 10372
consistent gets - examination
50 10853
execute count
37 30539
consistent gets
43 4 6627
redo entries
273 57059
db block gets
93 57480
recursive calls
56 60250
session logical reads
2 75550
db block changes
7748 7017416
table scan rows gotten
redo size
, ,
Oracle ( -
, , ) -
. Oracle -
, \0g
, -
.
101
, 10520,
8; 9/, -
PL/SQL
PL/SQL, catproc. sql. 10520 PL/SQL , -
. (..
), -
. ,
PL/SQL- (, ..): PL/SQL-
.
-
.
: P I , 2, 4. -
. 1 -
PKGI, P2 PKG2, ..
SQL> c r e a t e or replace package PKGI i s
2 procedure Pi; end;
3 /
Package created.
Package created.
Package created.
.;
5 end;
6 end;
7 /
Package created.
, ,
. SQL-
P I ( PKGI . pi),
.
SQL> create or replace package body PKGI is
2 procedure PI is
3 v cnt number;
4 begin
5 select count(*)
6 into v cnt
7 from emp
8 where empno > 0;
9 end;
10 end;
103
11 /
,
.
SQL> select object_name, object_type, status
2 from user_objects
3 where object_name in ('PKG1','PKG2','PKG3','PKG4';
! .
, , ,
. -
, , -
, .
,
,
. : -
,
PL/SQL.
,
- , PL/SQL. -
PL/SQL, ,
PL/SQL-
.
:
create or replace
package globals is
g_gender_m constant char(l) := 'M';
g_gender_f constant char(l) := 'F';
g error msg misc constant varchar2(80)
:= 'An unknown error has occurred';
104 2
end;
globals -
. , -
globals
(, , ).
, globals
.
, , globals, ,
PL/SQL-
.
, , .
, , -
PL/SQL-
.
. - ,
:
> ,
;
> ,
.
, -
.
globals, -
.
SQL> create or replace
2 package globals is
3 g_l constant number(5) := 1;
4 g_2 constant number(5) := 1;
5 g_3 constant number(5) := 1;
6 end;
7 /
Package created.
, , -
; SQL-.
, ,
. , -
.
105
Function created.
,
SQL-.
SQL> create or replace
2 function use_g2 return number is
3 x number;
4 begin
5 select globals.g_3 into x
6 from dual
7 where globals.g_2 = globals.g_2;
8 return x;
9 end;
10 /
Function created.
, , -
. DBMSJJTILITY . GET_TIME: -
,
. . -
, -
.
.
SQL- 50000 , -
.
SQL> declare
2 d number;
3 s number;
4 begin
5 s : = dbms utility.get time;
6 for i in 1 .. 1000000 loop
7 d := use gl;
8 end loop;
9 dbms output.put line((dbms utility.get_time-s)/100 I' seconds for
usage');
10 s : = dbms utility.get time;
11 for i in 1 .. 50000 loop
12 d := use g2;
13 end loop;
106 2
14 dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for
usage in SQL');
15 end;
16 /
1.42 seconds for usage
5.61 seconds for usage in SQL
.
.
SQL> create or replace
2 package globals is
3 g_l number(5) := 1;
4 g_2 number(5) := 1;
5 g_3 number(5) := 1;
6 g_new_global number (5) := 1;
7 end;
8 /
Package created.
,
USER_OBJECTS.
SQL> select object_name, status
2 from user_objects
3 where object_name in ('USE_G1','USEJ32');
USE_G2 INVALID
USE_G1 INVALID
, , .
, ,
, globals.
1:
8.1 -
(Virtual Private Database VPD).
VPD -
, .
. -
107
. -
( ), -
. ( -
Oracle 9 10, .)
glob, set_values,
glob.
create any context.
Context created.
set_values pkg_security. -
set_context dbms_session
: g_l, g_2 g_3 1, 2 3 .
, glob -,
globals. pkg_security.
SQL> create or replace
2 package PKG_SECURITY is
3 procedure set_values;
4 end;
5 /
Package created.
set_vaiues ,
glob.
logon .
, -
. , SYS_CONTEXT.
SQL> create or replace
2 function use_gl return number is
108 2
3 begin
4 return sys_context('glob','g_l');
5 end;
6 /
Function created.
SQL-.
SQL> create or replace
2 function use_g2 return number is
3 x number;
4 begin
5 select sys_context('glob','g_3') into x
6 from dual
7 where sys_context('glob','g_2') sys_context('glob','g_2');
8 return x;
9 end;
10 /
Function created.
,
.
SQL> exec set_values
15 ,
. -
1000000 50000.
SQL> declare
2 d number;
3 s number;
4 begin
5 s := dbms utility.get time;
6 for i in 1 .. 50000 loop
7 d := usegi;
8 end loop;
9 dbms output.put_line((dbms utility.get time-s)/100|| 1 seconds fo:
usage');
10 s := dbms utility.get time;
11 for i in 1 .. 50000 loop
12 d : = use_g2;
13 end loop;
14 dbms output;.put line((dbms utility.get time-s)/100||' seconds for
usage in SQL');
15 end;
16 /
8.48 seconds for usage
109
(
) SQL-
global s. -
, 20 .
PL/SQL, standard, -
. $ORACLE_HOME/rdbms/
admin/stdbody. s q i SYS_CONTEXT:
function SYS_CONTEXT(namespace varchar2, attribute varchar2)
return varchar2 is
varchar2(4000);
BEGIN
select sys_context(namespace,attribute) into from sys.dual;
return c;
end;
, SYS_CONTEXT PL/SQL
. , , -
( ) PL/
SQL,
SQL. SQL-
, . ,
.
- .
, :
SQL> select object_name, status
2 from user_objects
3 where object_name in ('USE_G1','USE_G2');
OBJECT_NAME STATUS
USE_G2 VALID
USE_G1 VALID
2
2: varchart
9.2, Oracle
( PL/SQL-) -
varcnar2. ,
. , -
PL/SQL- -
.
, -
, , -
, , .
, , ,
.
SQL> create or replace
2 package new_globals is
3 function g(gname in varchar2) return number;
4 end;
5 /
Package created.
. , num_tab,
varchar2.
, . -
, -
. , -
.
SQL> create or replace
2 package body new_globals i s
3
4 type num_tab i s table of number
5 index by varchar2(30);
6
7 n num_tab;
8
9 function g(gname in varchar2) return number is
10 begin
11 return n(gname);
12 end;
13
14 begin
15 n('g_l') := 1;
16 n('g_2') :- 1;
17 n('g_3') := 1;
18 end;
19 /
.
,
giobais.
SQL> create or replace
2 function use_gl return number is
3 begin
4 return new_globals.g('g_l');
5 end;
6 /
Function created.
Function created.
. ( -
1000000 .)
SQL> declare
2 d number;
3 s number;
4 begin
5 s := dbms_utility.get_time;
6 for i in 1 .. 1000000 loop
7 d := use_gl;
8 end loop;
9 dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for
usage');
10 s := dbms_utility.get_time;
11 for i in 1 .. 50000 loop
12 d := use_g2;
13 end loop;
14 dbms_output.put_line((dbms_utility.get_time-s)/100||' seconds for
usage in SQL');
15 end;
16 /
4.11 seconds for usage
11.36 seconds for usage in SQL
!
? -
.
SQL> create or replace
2 package body new_globals is
3
4 type num_tab is table of number
5 index by varchar2(30);
6
7 n num_tab;
8
9 function g(gname in varchar2) return number is
10 begin
11 return n(gname);
12 end;
13
14 begin
15 n('g_l') := 1;
16 n('g_2') := 1;
17 n('g_3') := 1;
18 n('g_new_global') := 1;
19 end;
20 /
.
SQL> select object_name, status
2 from user_Objects
3 where object_name in ('USE_G1','USE_G2');
USE_G2 VALID
USE_G1 VALID
, .
? , .
,
(). , ,
. ,
, , . ,
:
. ,
, , -
. , ,
, :
113
package extended_globals is
function get_numeric(gname in varchar2) return number;
function get_date(gname in varchar2) return date;
function get_varehar2 (gname in varchar2) return varchar2;
end;
, -
, . , , ,
.
, : -
. -
. , , -
.
, , -
(backtracking algorithms) -
,
. -
, ( ), -
.
.
SQL> create or replace
2 procedure A(p number) is
3 begin
4 if p < 5 then
5 B(p+1);
6 end if;
7 end;
8 /
, -
. -
, .
SQL> create package RECURSION is
2 procedure A(p number);
3 procedure (p number);
4 end;
Package created.
?
. -
, -
,
. .
?
115
Oracle ,
, - ,
.
, .
, , -
. , -
.
.
> , -
. ,
. -
.
> . -
$oRACLE_HOME/rdbms/admin, ,
Oracle : -
, .
.
, -
,
.
,
( PL/SQL -
) - Oracle (Forms, Reports
Graphics) PL/SQL-
.
, , Forms,
PL/SQL (
), fmx.
,
PL/SQL . -
:
PL/SQL.
,
PL/SQL . , -
common, tools u t i l s ,
.
, Oracle 7 ( -
PL/SQL)
,
.
116 2
(. ), -
.
, . -
, 1 1000,
, .
-
.
, , -
, -
, ,
.
.
,
"ORA-4031:unable to allocate bytes of
shared memory".
, ( , -
SYSDBA) ,
-
.
SQL> select bytes chunk size, count(*) no of chunks from
2 (
3 s e l e c t power(10,trunc(In(ksmchsiz)/In(10)))| t o ' | I
4 (power(10,trunc(In(ksmchsiz)/In(10))+1)-1) chunk_size
5 from x$ksmsp
6 where ksmchcls != 'perm' )
7 group by bytes
8 /
10 to 99 2487
100 to 999 16548
1000 to 9999 4573
10000 to 99999 15
100000 to 999999 18
1000000 to 9999999 7
-
.
117
procedure X300;
end;
1 .
, PL/SQL-, -
.
SQL> declare
2 varchar2(32767);
3 begin
4 for i in 1 . . 300 loop
5 x := x || ' procedure X'I IiI I';';
6 end loop;
7 execute immediate
8 'create or replace package MEMTEST is '||x|I' end; ';
9 x := replace(x,';',' is number; begin := 1; end;');
10 execute immediate
11 'create or replace package body MEMTEST is '||x||' end;';
12 end;
13 /
System a l t e r e d .
PL/SQL,
, , , ,
, .
,
PL/SQL-: PL/SQL-, -
. , -
, . -
. ,
.
SQL> create t a b l e x ( number, varchar2(30));
Table created.
, -
. . -
, deterministic. -
Oracle ,
( , )
.
SQL> create or replace
2 package FBI is
3 function ix(p varchar2) return varchar2 deterministic;
4 end;
5 /
Package created.
.
SQL> create or replace
2 package body FBI is
3 function ix(p varchar2) return varchar2
4 deterministic is
5 begin
6 return p;
7 end;
8 end;
120 2
9 /
Index created.
Table analyzed.
, , autotrace
SQL*Plus SQL-.
SQL> set autotrace on
SQL> select *
2 from x
3 where FBI.ix(y) = 'xxxxxl23';
X Y
123 xxxxxl23
Execution Plan
. ,
. , ,
, , .
, .
-
. ,
'abc'.
SQL> create or replace
2 package body FBI is
3 function ix(p varchar2) return varchar2
4 deterministic is
5 begin
6 return pI I'abc';
7 end;
8 end;
121
9 /
Oracle , ,
, . -
" " , -
. -
,
. SQL-
, , -
:
SQL> select *
2 from
3 where FBI.ix(y) = '123';
* *
123 123
, , : , -
Y ,
. ,
, .
SQL> select /*+ FULL(x) */ *
2 from x
3 where FBI.ix(y) = 'xxxxxl23';
no rows selected
, .
, , -
(.. f uncidx_status -
user_indexes disabled),
. , -
( ),
- , -
. PL/SQL-, , -
.
-
, -
PL/SQL-, -
Oracle.
122 2
, PL/SQL-, -
SYS, .
9.2.
SQL> select object_name
2 from dba_objects
3 where owner = 'SYS'
4 and object_type = 'PACKAGE';
OBJECT NAME
CONNECTIONINTERFACE
CURSORMANAGERINTERFACE
DATABASEINTERFACE
DATAPROVIDERINTERFACE
DATATYPEIDCONSTANTS
DBMSOBJG
DBMSOBJG2
DBMSOBJGWRAPPER
DBMSOBJG_DP
DBMSZEXP_SYSPKGGRNT
DBMS_ALERT
DBMS_APPCTX
DBMS APPLICATION INFO
XSLPROCESSOR
XSLPROCESSORCOVER
XSLSTYLESHEETCOVER
300 ! , ,
, Oracle. -
, Oracle,
"Supplied PL/SQL Packages and Types Reference". -
,
Oracle. , Oracle
" " -
. Oracle
PL/SQL, ( ) .
Oracle -
. ,
. , " "
dbms_f . " Web-"
u t l h t t p HTTP- -
Oracle, " PL/SQL" -
( -
).
123
,
:
> . ,
( ) , ,
Oracle ;
> ,
, -
Oracle.
-
. -
.
. , PL/SQL
:
SQL> create or replace
2 package stack is
-
.
3 type module_list is
4 table of varchar2(80)
5 index by binary_integer;
6
:
.
7 procedure push(module_name varchar2);
8 procedure pop;
9 procedure show_stack;
10
11 end;
12 /
Package created.
, .
SQL> create or replace
2 package body stack is
3
4 m module_list;
5
6 procedure push(module_name varchar2) is
7 begin
8 m(m.count+l) := module name;
124 2
9 end;
10
11 procedure pop is
12 begin
13 m.delete(m.count);
14 end;
15
16 procedure show_stack is
17 begin
18 for i in 1 .. m.count loop
19 dbms_output.put_line(rpad('-',i,-')||m(i)) ;
20 end loop;
21 end;
22
23 end;
24 /
, PL/SQL, -
-
. ,
. :
.
SQL> create or replace
2 procedure pi is
3 begin
4 stack .push('PI1);
5 stack .show stack;
6 stack .pop;
7 end;
8 /
Procedure created.
Procedure created.
6 stack.pop;
7 end;
Procedure created.
show_stack pi
.
SQL> exec ;
-
2
1
. -, PL/SQL-npo-
, , ,
. , -
PL/SQL-, -
. - ( ) -
Oracle!
pi :
SQL> create or replace
2 procedure pi is
3 begin
4 dbms_output.put_line(
5 substr(dbms_utility. format_call_stack, 1, 255));
6 end;
7 /
Procedure created.
FORMAT_CALL_STACK dbms_utiiity
. stack ,
- -
PL/SQL-.
DBMS_UTILITY.FORMAT_CALL_STACK.
SQL> exec ;
PL/SQL Call Stack
object line object
handle number name
700000003f56250 3 procedure SCOTT .PI
700000003f4c3cO 4 procedure SCOTT .P2
700000003f47e38 4 procedure SCOTT .P3
700000003f44e98 1 anonymous block
, PL/SQL- . , -
126 2
,
.
,
DBMS_UTILITY . FORMAT_CALL_STACK, -
, , dbms_application_inf ,
" PL/SQL".
dbms_utility ,
. ,
DBMS_UTILITY.GET_TIME ,
. -
.
( )
.
SQL> exec dbms_utility.get_dependency('TABLE',user,'EMP');
DEPENDENCIES ON SCOTT.EMP
*TABLE SCOTT.EMP()
* PACKAGE BODY SCOTT.PKG()
DEPENDENCIES ON SCOTT.EMP
*TABLE SCOTT.EMP()
* PACKAGE BODY SCOTT.PKG()
. , Oracle 9.2.0.4 -
:
SQL> variable bl varchar2(64)
SQL> variable b2 varchar2(64)
SQL> exec dbms_utility.db_version(version=>:bl,compatibility=>:b2);
SQL> print
Bl
9.2.0.4.0
127
SQL> print 2
9.2.0.0.0
PORT_STRING
IBMPC/WIN_NT-8.1.0
, port_string -
, , , .
DDL
( ) , -
DDL. -
, , ,
Oracle , ,
.
, . Google
, .
create table,
.
SELECT DECODE(T1.COLUMN_ID,1,'CREATE TABLE ' ||
T1.TABLE_NAME I I ' (',' ' ) A,
T1.COLUMN_NAME B, Tl.DATAJTYPE ||
DECODE(Tl.DATA_TYPE, 'VARCHAR2', '('II
TO_CHAR(T1.DATA_LENGTH)||')', 'NUMBER','('I|
TO_CHAR(T1.DATA_PRECISION)||
','||TO_CHAR(Tl.DATA_SCALE)||')',
1
CHAR',' (' | |TO_CHAR(Tl.DATA_LENGTH) | | ') ') I I
DECODE(T1.COLUMN_ID,MAX(T2.COLUMN_ID), ');',',')
FROM USER_TAB_COLUMNS Tl, USER_TAB_COLUMNS T2
WHERE T1.TABLE_NAME = T2.TABLE_NAME
GROUP BY T1.COLUMN_ID, T1.TABLE_NAME, Tl.DATA_TYPE,
T1.DATA_LENGTH, Tl.DATA_SCALE, Tl.COLUMN_NAME, Tl.DATA_PRECISION
ORDER BY T1.COLUMN_ID;
, -
DDL , , -
, , , -
, ,
, . -
, . ,
128 2
, Oracle
. Metalink.
DECLARE
cursor curO is
select table_name,TABLESPACE_NAME,PCT_FREE,PCTJJSED,
INIJTRANS,MAXJTRANS,
INITIAL_EXTENT,NEXT_EXTENT,PCT_INCREASE
from user_tables
order by table_name;
tab_name varchar2(40);
tabsp_name varchar2(40);
mpct_free number;
mpct_used number;
mini_trans number;
mmax_trans number;
mini_ext number;
mnext_ext number;
mpct inc number;
col_name varchar2(40) ;
ct number : 0;
line_ct number := 0;
BEGIN
delete from AAA;
ct := 0;
for curl_rec in curl(tab_name) loop
ct := ct + 1;
if ct = 1 then
129
insert into AAA(fl, line )
values (line_ct ,
' 'II curl_rec.column_name||' 'II
curl_rec.data_type||
decode(curl_rec.data_type, 'VARCHAR2',' ('I I
to_char(curl_rec.data_length)I|')',
'NUMBER',decode(curl_rec.data_precision, null,'',
'<'I Ito_char(curl_rec.data_precision) I I
decode(curl_rec.data_scale, null, ' ) ' , ','11
to_char(curl_rec.data_scale)||')' ) ), '')ll
decode(curl_rec.nullable, 'Y 1 , '', ' NOT NULL') ) ;
line_ct := line_ct + 1;
else
insert into AAA(fl, line)
values (line_ct, ' ,'I I curl_rec.column_name| | ' '| |
curl_rec.data_type||
decode(curl_rec.data_type, 'VARCHAR2','('I I
to_char(curl_rec.data_length)II') 1 ,
'NUMBER',decode(curl_rec.data_precision, null,'',
'('||to_char(curl_rec.data_precision)|[
decode(curl_rec.data_scale, null, ' ) ' , ','M
to_char(curl_rec.data_scale)II')' ) ), '')I I
decode(curl_rec.nullable, 'Y 1 , '', ' NOT NULL 1 ) ) ;
line_ct := line_ct + 1;
end if;
end loop;
insert into AAA (fl, line )
values(line_ct, ' ) ' ) ;
line_ct := line_ct + 1;
insert into AAA (fl, line )
values (line_ct, ' PCTFREE ' | | mpct_free | | ' PCTUSED ' I I
mpct_used ) ;
line_ct := line_ct + 1;
insert into AAA (fl, line )
values (line_ct, ' INITRANS ' | | mini_trans I I ' MAXTRANS ' | |
mmax_trans);
insert into AAA (fl, line )
values (line_ct, ' TABLESPACE '||tabsp_name ) ;
line ct := line ct + 1;
insert into AAA~(fl, line )
values(line_ct, ' STORAGE ( INITIAL ' || mini_ext || ' NEXT '
I| mnext_ext |I ' PCTINCREASE ' || mpct_inc || ' ) ; ' ) ;
line_ct := line_ct + 1;
insert into AAA (fl, line )
values (line_ct, 'REM NEXT TABLE ');
line_ct := line_ct + 1;
commit;
end loop;
END,
5 . 348
130 2
,
. ,
. , -
DDL .
, , -
! GET_DLL dbmsjnetadata
DDL (CLOB). -
, DDL emp SCOTT
SELECT, .
SQL> select dbmsjnetadata.get_ddl('TABLE','EMP','SCOTT')
2 from dual;
"ENAME" VARCHAR2(10),
. ,
DDL. , -
, -
:
begin
DBMS_METADATA.SET_TRANSFORM_PARAM(
DBMS_METADATA.SESSIONJTRANSFORM,
1
STORAGE',
false) ;
end;
DDL . DDL -
. ,
:
SQL> select dbms_metadata.get_ddl('USER','SCOTT')
2 from dual;
, -
DDL, . "PL/SQL Supplied Packages Guide". -
, .
DBMSROWID
dbms_rowid, -
.
.
( ) .
( ),
dbms_rowid . ,
emp. 10
( , ,
8 1981 ).
SQL> update emp
2 set sal - sal * 1.1
3 where hiredate < to date('08/SEP/1981','DD/MON/YYYY1);
6 rows updated.
20, 30.
SQL> update emp set deptno = 30 where deptno = 20;
(...)
, , ,
, . -
dbms_rowid . -
V$SESSION, , .
, row_, ,
, ,
emp.
SQL> s e l e c t row_wait_obj#, row_wait_file#,
2 row_wait_block#, row_wait_row#
3 from v$session
4 where row_wait_obj# in (
5 select data object id
6 from user_objects
49627 7 138 0
dbms_rowid,zuM -
, .
132 2
SQL> select *
2 from emp
3 where rowid = dbms_rowid.rowid_create(1,4 9627,7,138,0);
,
, , -
. , -
,
.
, (, )
30 . / -
. -
, -
. ( )
(pipes) .
, ,
.
:
1. ,
.
2. 1.
3. , 2, , -
.
4. .
:
1. 1.
2. , 1.
3. 2.
4. , ( - ,
).
5. 1.
, -
:
> , ;
> , ,
-
;
133
> ,
, ,
.
,
. (alerts) ,
, ,
-
( ) , -
, .
, -
.
. ,
,
, -
.
, ,
, , - -
! (Job Queue)
7, , ,
.
,
:
dbms_job. submit (: job, ' ,_>__; ') ;
! :
, . 36 -
8 1000 9. , ,
,
. -
, -
.
. ,
. -
list_of_files, ,
.
SQL> create table LIST_OF_FILES (
2 fname varchar2(30),
3 fdir varchar2(30)) ;
Table created.
1 row created.
134 2
,
uti_file.fremove ( )
. ,
, .
SQL> create or replace
2 trigger DEL_FILE
3 before delete on LIST_OF_FILES
4 for each row
5 declare
6 j number;
7 begin
8 dbms_job.submit(j,'utl_file.fremove('''|I
9 :old.fdir|I''','''I I:old.fname| " ) ; ' ) ;
10 end;
11 /
Trigger created.
.
/tmp/demo.dat. , -
.
SQL> !ls /tmp/demo.dat
/tmp/demo.dat
.
SQL> delete from list_of_files;
1 row deleted.
, -
. , -
. , -
. , - .
SQL> !ls /tmp/demo.dat
/tmp/demo.dat
-
, .
SQL> commit;
Commit complete.
DBMSJOB . 6, "".
135
. -
, , Oracle, -
PL/SQL-.
.
PL/SQL ( ,
, ) .
-
, -
, . -
, , , ,
, -
, , . .
, , .
I /VClDCl J
1 , PL/SQL, -
SQL. ,
SQL, PL/SQL -
Oracle. , PL/SQL
, ,
, .
, , . -
, , , -
.
, ,
, . :
> ;
> , ;
v ,
;
> , SQL--
.
SELECT INTO (.. -
) PL/SQL :
> , -
;
> (, -
), NO_DATA_FOUND;
> , -
TOO_MANY_ROWS.
, -
. , PL/SQL--
, , TOO_MANY_ROWS, -
,
. ,
138 3
: , 1 -
. ,
():
> ;
> ;
> ( , -
TOO_MANY_ROWS);
> .
, -
. , PL/SQL
.
Oracle 7.1 (-
fetching). ,
, . -
, -
. , -
. " "
PL/SQL, ,
, : -
NO_DATA_FOUND
TOO_MANY_ROWS. .
,
, . Google -
:
" , , , -
, -, , ,
.
";
" .
, ";
" , , ,
".
, , , " "
, , "
", ,
. , -
, , -
, ,
, .
139
, -
. -
,
-
, ' .
SQL> create table one_row_tab ( x primary key )
2 organization index as select 1 from dual;
Table created.
, 50000
, .
SQL> create or replace
2 procedure implicit is
3 dummy number;
4 begin
5 for i in 1 .. 50000 loop
6 select 1
7 into dummy
8 from one_row_tab;
9 end loop;
10 end;
11 /
Procedure created.
Procedure created.
' , , PL/SQL
( ). ,
, "" .
140 3
PL/SQL-, , . ,
"".
SQL> exec implicit;
Elapsed: 00:00:04.02
SQL> exec e x p l i c i t ;
Elapsed: 00:00:05.07
50000
1000000, 20
. , PL/SQL ,
,
.
.
-
, , ,
.
-
"" ,
, : -
PL/SQL ,
OPEN CLOSE .
:
SQL> create or replace
2 procedure explicit2 is
3 cursor explicit_cur is
4 select 1
5 from one_row_tab;
6 dummy number;
7 begin
8 open explicit_cur;
9 for i in 1 .. 50000 loop
10 fetch explicit_cur
11 into dummy;
12 end loop;
13 close explicxt_cur;
14 end;
15 /
Procedure created.
141
Elapsed: 00:00:00.00
! , , .
! . , , PL/SQL
, -
, PL/SQL-, ,
PL/SQL-. -
. SELECT -
, 50000 -
. "
" .
SQL> create or replace
2 procedure explicit2 is
3 cursor explicit_cur is
4 select 1
5 from one_row_tab;
6 dummy number;
7 begin
8 open explicit_cur;
9 for i in 1 .. 50000 loop
10 fetch explicit_cur
11 into dummy;
12 if explicit_cur%found then
13 dbms_output .put_line(' ');
14 end if;
15 end loop;
16 close explicit_cur;
17 end;
18 /
Procedure created.
Elapsed: 00:00:00.00
50000 .
, , , " -
".
142 3
, , ,
.
, ,
, "", -
.
SQL> create table EXPLICIT_IS_BEST
2 ( x number, char(100));
Table created.
10000 ,
1. Y ,
. IMPLICIT
EXPLICIT EXPLICIT_IS_BEST, = 1.
, 50000 , -
.
SQL> create or replace
2 procedure implicit is
3 dummy number;
4 begin
5 for i in 1 .. 50000 loop
6 select 1
7 into dummy
8 from explicit is best
9 where x = 1;
10 end loop;
11 end;
12 /
Procedure created.
11 fetch explicit_cur
12 into dummy;
13 close explicit_cur;
14 end loop;
15 end;
16 /
Procedure created.
, , -
.
SQL> exec implicit
Elapsed: 00:06:41.00
SQL> exec e x p l i c i t
Elapsed: 00:00:05.04
, .
,
(
). , ,
.
, , , -
. () Oracle -
. , ,
= 1, "" (.. ).
DELETE INSERT
. , = 1.
SQL> delete from explicit_is_best
2 where x= 1;
1 row deleted.
SQL> insert into explicit_is_best
2 values (1,'padding');
1 row created.
SQL> commit;
Commit complete.
, ,
,
144 3
, Oracle ; -
.
SQL> select x
2 from explicit_is_best;
5
6
7
9998
9999
10000
1
^
10000 rows selected.
?
.
SQL> exec implicit
Elapsed: 00:06:41.00
SQL> exec e x p l i c i t
Elapsed: 00:06:42.72
,
, .
, -
, .
.
. -
, , ,
, :
select . . . from . . . where . . . and rownum = 1
, = 2
( - )
ROWNUM = 1 SQL-, ,
.
145
Procedure created.
Elapsed: 00:00:04.05
-
( 5,04 ), , -
.
, ,
. -
FOR . FOR -
, , -
Oracle , .
,
, -
SELECT . -
FOR:
SQL> begin
2 for i in ( select ename from emp ) loop
3 dbms_output.put_line(i.ename);
4 end loop;
5 end;
6 /
SMITH
ALLEN
JAMES
FORD
MILLER
, SELECT -
, , -
, , SQL%ROWCOUNT SQL%FOUND. -
FOR .
-
?
? .
.
, , :
> ,
;
> .
%ROWCOUNT
. , -
, , -
, .
SQL> declare
2 cursor is select ename from emp ;
3 begin
4 for i in loop
5 null;
6 end loop;
7 dbms_output.put_line(c%rowcount) ;
8 end;
9 /
declare
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 7
, -
.
-
1, :
SQL> declare
2 cnt pls_integer : 0;
3 begin
4 for i in (select ename from emp) loop
5 cnt := cnt + 1;
6 end loop;
7 dbms_output.put_line(cnt);
8 end;
-
.
147
ROWNUM ,
.
:
", , <>. , -
<>".
- -
, , - -
SQL. , -
" - ".
SQL :
SQL> select count(*)
2 from emp
3 where hiredate > trunc(sysdate,'MM');
, ; -
, -
, .
PL/SQL,
%FOUND .
SQL> c r e a t e or replace
2 function IS_EMP_THERE return varchar2 i s
3 cursor i s
4 select 1 from emp
5 where hiredate > trunc(sysdate,'MM);
6 r number;
7 v varchar2(3);
8 begin
9 open C;
10 fetch into r;
11 if C%FOUND then
12 v := 'YES';
13 else
14 v := 'NO';
15 end if;
16 close C;
17 return v;
18 end;
19 /
Function created.
, , ,
, -
, 1, "
PL/SQL", PL/SQL,
148 3
SQL. , -
SQL.
select count(*)
from dual
where exists ( s e l e c t n u l l from emp where h i r e d a t e > trunc(sysdate,'MM 1 ))
1 ( ),
( ), PL/SQL .
-
PL/SQL-, -
. ,
. -
. -
, .
SQL> create or replace
2 procedure PROCESS_EMP is
3 cursor is
4 select empno, sal, comm
5 from emp;
6 v bonus number := 10000;
7 begin
for i in loop
9 v bonus :- v bonus + i.comm / i.salj
10 end loop;
11 exception
12 when zero divide then
13 if C%ISOPEN then
14 close C;
15 end if;
16 end;
17 /
Procedure created.
, ,
. . -
-
( ). , -
,
, , .
N
, ,
( ) .
: -
149
, -
-
. , -
, Y,
. 500 ,
.
SQL> create or replace
2 procedure explicit is
3 cursor explicit_cur is
4 select x
5 from explicit_is_best
6 order by desc;
7 dummy number;
8 begin
9 for i in 1 .. 500 loop
10 open explicit_cur;
11 fetch explicit_cur
12 into dummy;
13 close explicit_cur;
14 end loop;
15 end;
16 /
Procedure created.
SQL-
, (inline view).
SQL> create or replace
2 procedure implicit is
3 dummy number;
4 begin
5 for i in 1 .. 500 loop
6 select x into dummy
7 from ( select x
8 from explicit_is_best
9 order by desc )
10 where rownum = 1;
11 end loop;
12 end;
13 /
Procedure created.
, , -
. -
.
SQL> exec implicit;
Elapsed: 00:00:09.09
Elapsed: 00:00:23.06
. -
, "-
" . -
ROWNUM, ORDER BY,
Oracle SQL- , -
, SQL-, -
.
, , ,
SQL- -
. ,
, SQL-, -
, , -
. , ,
, ,
.
,
. , , -
, , -
4, " ".
- ,
. , , , -
, , -
.
,
, (
).
, , ,
,
.
,
(.. -
, , CICS-COBOL). -
, -
151
. , .
-
,
, , -
.
PL/SQL ( -
REF-). -
. -
PL/SQL;
, ,
Java-, Oracle, ,
Forms Developer Suit, * OCI.
PL/SQL , .. -
SQL-, -
; .
, ,
, PL/SQL- , -
, PL/SQL . , -
; -
.
. ,
.
SQL> create or replace
2 function emp_list return sys_refcursor is
3 re sys_refcursor;
4 begin
5 open re for select * from emp;
6 return re;
7 end;
8 /
Function created.
SYS_REFCURSOR 9. 8, -
type s y s _ r e f cursor i s r e f cursor RC.
LISTEMPS, -
. ,
, ,
EMP_LIST.
152 3
Procedure created.
LIST_EMPS
.
SQL> exec list_emps;
7369,1V/DEC/8O
7499,20/FEB/81
7521,22/FEB/81
7566,02/APR/81
7654,28/SEP/81
7698,01/MAY/81
7782,09/JUN/81
7788,19/APR/87
7839,17/NOV/81
7844,08/SEP/81
7876,23/MAY/87
7900,03/DEC/81
7902,03/DEC/81
7934,23/JAN/82
, . -
. -
,
SQL*Plus (
).
SQL> variable x refcursor
SQL> declare
2 r emp%rowtype;
3 begin
4 :x := emp list;
5 loop
6 fetch :x into r;
7 exit when :x%notfound;
153
8 dbms_output.put_line(r.empnolI','IIr.hiredate);
9 end
d loop;
l
10 close :x;
11 end;
12 /
7369,17/DEC/80
7499,20/FEB/81
7521,22/FEB/81
7566,02/APR/81
7654,28/SEP/81
7698,01/MAY/81
7782,09/JUN/81
7788,19/APR/87
7839,17/NOV/81
7844,08/SEP/81
7876,23/MAY/87
7900,03/DEC/81
7902,03/DEC/81
7934,23/JAN/82
.
(SQL*Plus) PL/SQL- -
. , -
(, SQL*Plus) -
, EMPLIST. PRINT,
,
.
SQL> exec :x := emp_list;
SQL> print x
"", , -
.
"" ( SQL*Plus)
( Java, Pro*C ..), ,
-
, .
PL/SQL-, , SQL-
, PL/SQL-. ,
V_BONUS -
:
SQL> declare
2 v_bonus number := 10000;
3 v_max_sal number;
4 begin
5 select max(sal)+v_bonus
6 into v_max_sal
7 from emp;
8 end;
9 /
, ,
,
. , -
, .
? , . -
(cursor expression) 9.
:
s e l e c t deptno, dname,
cursor(select empno, ename
from emp
where deptno = d.deptno)
from dept d;
.
( DEPT),
-
, .
SQL*Plus , . SQL*Plus
DEPT SQL*Plus -
.
155
5 from dept d;
CURSOR STATEMENT : 3
EMPNO ENAME
7782 CLARK
7839 KING
7934 MILLER
CURSOR STATEMENT : 3
EMPNO ENAME
7369 SMITH
7566 JONES
7788 SCOTT
7876 ADAMS
7902 FORD
, ,
DEPT.
. ,
:
> DEPT;
> ( -
):
> ;
> .
,
" " , -
. -
( ):
open dept_cursor
for each row in dept_cursor
156 3
open emp_cursor
for each row in emp_cursor
print details
close emp_cursor
open cust_cursor
for each row in cust_cursor
print details
close cust_cursor
, , -
-
, .
.
, SQL*Plus -
, . -
DEPT_EMP_CUST, ,
DEPT
CUSTOMER.
SQL> create or replace
2 function dept_emp_cust return sys_refcursor is
3 re sys_refcursor;
4 begin
5 open re for
6 select deptno, dname,
7 cursor(select empno, ename
8 from emp
9 where deptno = d.deptno) emps,
10 cursor(select custid, custname
11 from customers
12 where purchasing_dept = d.deptno) custs
13 from dept d;
14 return re;
15 end;
16 /
Function created.
, SQL*Plus,
-
print DEPT,
.
SQL> variable x refcursor
SQL> exec :x := dept_emp cust;
SQL> print x
157
CURSOR STATEMENT : 3
EMPNO ENAME
-
7782 CLARK
7839 KING
7934 MILLER
CURSOR STATEMENT : 4
CUSTID CUSTNAME
7 Cust7
9 Cust9
14 Custl4
< >
, ,
,
.
, SQL-
. : -
, . , -
AUTOTRACE SQL*P1US2 ,
,
, . -
.
SQL> set arraysize 50
SQL> set autotrace on statistics
SQL> select empno, deptno no cursor expression here
2 from emp
3 /
Statistics
0 recursive calls
0 db block gets
1249 consistent gets
244 physical reads
0 redo s i z e
603709 bytes sent v i a SQL*Net t o c l i e n t
2
AUTOTRACE. .
9 SQL*Plus Users Guide and Reference.
158 3
11488 bytes received via SQL*Net from client
1001 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
50000 rows processed
, -
. , ,
,
, , .
SQL> create table IX ( number primary key )
2 organization index;
Table created.
Table analyzed.
Statistics
-
- consistent gets
1249 75112! , -
, ,
ix, .
, , ,
.
SQL*Plus (array fetching), -
, 200
50 . -
,
TKPROF, , .
159
select *
from
emp where rownum < 200
200 -
. ,
, , .
select empno,
cursor(select x
from ix) from emp where rownum < 200
.
, -
.
, , -
.
,
PL/SQL ( -
, Oracle).
PL/SQL-, -
-
, Oracle.
, -
, ,
.
, , -
PL/SQL.
, -
.
4
,
COBOL .
(
, -
). COBOL
, ,
-
, COBOL . -
:
YEAR-END-STRING PIC X(8)
YEAR-END-NUM REDEFINES YEAR-END-STRING PIC 99999999
, , YEAR-END, -
,
. .
.
(YEAR-END-STRING) "HELLO",
(YEAR-END-NUM).
COBOL- , ,
( ,
!).
PL/SQL-,
. ,
.
PL/SQL
. "" , -
, . -
Oracle ,
- . -
:
> ;
. 348
162 4
> ( , );
> . -
,
.
, ,
, -
. , , , -
, , .. ,
, -
. -
PL/SQL . , -
:
declare
v_salary number;
v_surname varchar2(2000);
, -
, , -
. , -
? , .
,
. PL/SQL , -
, .
%TYPE
PL/SQL
, , -
%TYPE . , -
%TYPE .
"... , ()
" PL/SQL User's Guide.
, , -
PL/SQL-.
,
. ,
42 .
. -
. ,
, ,
"" (-
163
, ) -
( ) .
, -
( )?
, "" .
%TYPE . -
: .
-
.
SQL> @$ORACLE_HOME/sqlplus/demo/demobld.sql
Building demonstration tables. Please wait.
Demonstration table build is complete.
, : -
. -
%TYPE , , .
SQL> create or replace
2 procedure WITHOUTJTYPE is
3 v_salary number(7,2);
4 begin
5 select max(sal)
6 into v_salary
7 from emp;
8 end;
9 /
Procedure created.
Procedure created.
SMITH EMPNO = 7369, ,
. , -
SMITH, -
SAL .
SQL> alter table EMP modify sal number(10,2);
Table altered.
164 4
SQL> update EMP set sal = 1000000
2 where EMPNO = 7369;
1 row updated.
WITHOUTJTYPE.
SQL> exec WITHOUTJTYPE;
BEGIN WITHOUT TYPE; END;
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at "WITHOUTJTYPE", line 4
ORA-06512: at line 1
,
. , V_SALARY
. , -
%TYPE, . ,
WITH_TYPE .
SQL> exec WITH_TYPE
%TYPE -
, -
. , 2, "-
",
.
%TYPE
, , -
? -
%TYPE . ,
, 30- :
procedure MY_PROC(p_input varchar2) is
vl varchar2(30);
v2 varchar2(30);
v3 varchar2(30) ;
v4 varchar2(30) ;
begin
vl := p_input;
end;
,
MY_PKG . GLOB_VAR,
:
165
package MY_PKG is
glob_var varchar2(40);
end;
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "MY_PROC", line 33
ORA-06512: at line 1
,
vi. ( MY_PKG) ,
vi
40 .
. .
> ? ..
MY_PKG . GLOBJVAR MY_PROC, -
, , GLOB_VAR
MY_PROC.
> V2, V3 V4?
> ?
%TYPE
PL/SQL-. MYPROC , -
MY_PKG . GLOBJVAR.
create or replace
procedure MY_PROC(p_input varchar2) is
vl my_pkg.glab_var%type;
v2 my_pkg.glab_var%type;
v3 my_pkg. glob_var%type;
v4 my_pkg. glob_var%type;
begin
end;
, MY_PKG . GLOB_VAR. MY_PROC
MYPKG, .
MY_PKG, , , GLOB_VAR,
60- ,
SQL> create or replace
2 package MY_PKG is
3 glob_var varchar2(60) := zpad('x',60);
4 end;
5 /
Package created.
166 4
MY_PROC
, .
SQL> exec MY_PROC(my_pkg.glob_var);
( )
, MY_PROC MY_PKG . GLOB_VAR.
USER_DEPENDENCIES, ,
MYPROC MY_PKG, , .
,
PL/SQL- ,
. MY PROC
, ,
. APPLICATIONJTYPES.
SQL> create or replace
2 package APPLICATIONJTYPES is
3 subtype short_varchar2 is varchar2(40);
4 end;
5 /
Package created.
MY_PROC MY_PKG
, APPLICATIONJTYPES.
SQL> create or replace
2 procedure MY_PROC(p_input application_types.short_varchar2) is
3 vl application_types.short_varchar2;
4 v2 applicatlon_types.short_varchar2;
5 v3 applcaton_types.short_varchar2;
6 v4 application_types.short_varchar2;
7 begin
9 null;
9 end;
10 /
Procedure created.
Package created.
167
SHORT_VARCHAR2, -
APPLICATION_TYPES .
, PL/SQL-
, , . -
, ,
2 .
, ,
.
-
. PL/SQL- -
(, , ). -
, Oracle
. VARCHAR2,
.
, , -
. -
, :
. ,
DBMS_UTILITY.GET_TIME , -
, 1000000
.
SQL> create or replace
2 procedure data_type_test is
3 x date;
4 varchar2(12) : = '01-MAR-03';
5 t number := dbms_utility.get_time;
6 begin
7 for i in 1 .. 1000000 loop
8 x := y; implicit char to date
9 end loop;
10 dbms_output.put_line((dbms_utility.get_time-t)||'cs');
11 end;
12 /
Procedure created.
.
SQL> set serverout on
SQL> exec data_type_test
771cs ( )
! , , -
, 140000 .
, 7,7 PL/SQL-,
168 4
. -
? .
, , , -
.
SQL> create or replace
2 procedure data_type_test is
3 x date;
4 x%type :- to_date('01-MAR-03');
5 t number := dbms_utility.get_time;
6 begin
7 for i in 1 .. 1000000 loop
8 x := y;
9 end loop;
1
10 dbms_output.put_line((dbms_utility.get_time-t)I|'cs );
11 end;
12 /
Procedure created.
.
SQL> exec data_type_test
31cs ( )
, ! 96%
. , - -
.
-
. PL/SQL , -
( "i" ) INTEGER. -
I X, INTEGER , -
, , -
.
SQL> create or replace
2 procedure num_test_as_integer is
3 x integer;
4 t number := dbms_utility.get_time;
5 begin
6 for i in 1 .'. 10000000 loop
7 x := i;
8 end loop;
9 dbms_output.put_line((dbms_utility.get_time-t)|I'cs');
10 end;
11 /
Procedure created.
,
PLS_INTEGER.
SQL> create or replace
2 procedure num_test_as_pls is
3 x pls_integer;
4 t number := dbms_utility.get_time;
5 begin
6 for i in 1 . . 10000000 loop
7 x:-'i;
8 end loop;
9 dbms_output.put_line((dbms_utility.get_time-t)||'cs');
10 end;
11 /
Procedure created.
, ,
- PLS_INTEGER:
SQL> exec num_test_as_pls
319cs ( 5 )
, , ,
PLS_INTEGER. , ,
PLS_INTEGER.
SQL> begin
2 for i in power(2,31) .. power(2,31)+10 loop
3 null;
4 end loop;
5 end;
6 /
begin
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at line 2
, , PLS__INTEGER,
INTEGER, .
-
%ROWTYPE
%TYPE PL/SQL- , -
( ) PL/SQL-
. , ?
PL/SQL-, ,
. PL/SQL -
%ROWTYPE.
SQL-:
170 4
select *
into varl, var2, ..., varN
from table
where < >
%TYPE VARI,
VAR2 .., . ,
, ,
? , PL/SQL, ,
.
PL/SQL : -
%ROWTYPE. PL/SQL- -
. WITH_ROWTYPE,
.
SQL> create table T (
2 cl number,
3 c2 number ) ;
Table created.
1 row created.
Procedure created.
R ,
. , -
.
SQL> exec WITH_ROWTYPE
Table altered.
171
Table altered.
Table altered.
Table dropped.
3 c2 number);
Table created.
Table altered.
172 4
.
SQL> alter view V compile;
View altered.
.
SQL> desc V
Name Null? Type
Cl NUMBER
C2 NUMBER
SQL> desc T
Name Null? Type
Cl NUMBER
C2 NUMBER
C3 NUMBER
.
, , SELECT * FROM TABLE, -
s e l e c t c o l l , col2, . . . , colN from t a b l e
, -
SELECT *. - , -, -
SELECT * . -
,
, .
, , -
, %ROWTYPE, ,
. , -
WITH_ROWTYPE
:
SQL> drop table T;
Table dropped.
3 c2 number );
Table created.
1 row created.
173
Table created.
, -
, , -
%ROWTYPE. , -
INSERT, :
SQL> alter table T add number;
Table altered.
Table altered.
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object WITH_ROWTYPE is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
7 8 Oracle
INSERT.
, :
.
DML, 9.2,
.
174 4
DML
, %ROWTYPE,
PL/SQL , -
INSERT UPDATE. WITH_ROWTYPE ,
DML- -
. ( 1, -
.)
SQL> create or replace
2 procedure WITH_ROWTYPE is
3 r T%ROWTYPE;
4 begin
5 select *
6 into r
7 from T
3 where rownum = 1;
9
10 insert into Tl
11 values r/
12 end;
13 /
Procedure created.
, T I .
SQL> alter table T add c5 number;
Table altered.
Table altered.
- .
SQL> exec WITH_ROWTYPE
10 update Tl
11 set row = r
12 where rownum = 1;
13 end;
14 /
Procedure created.
DELETE ,
DELETE .
DML- " ".
, DML-
.
SELECT * FROM DBAJTYPES
- ,
(, Spatial Text). ,
"" "" "", " " ..,
Oracle : " -
- ".
8.0
, , - ,
, , ,
. SQCPlus ,
SQL*Plus .
OracleWorld2002 - -
: " - -
, ?".
, Oracle -
. ,
. , ,
, .
SQL> create or replace type STOLEN_ITEMS as object
2 firstname varchar2(30),
3 surname varchar2(30),
4 date of birth date,
5 incident date date.
6 item count number (4),
7 items retrieved varchar2(1)
8 )
9
created.
176 4
SQL> create table CRIMES (
2 person_id number(10),
3 crime_details stolen_items ) ;
Table created.
TEXT
DBA_TAB_COLUMNS -
DBA_TAB_COLS. . DBA_TAB_COLS
, , , " " -
.
SQL> select column_name, hidden_column, data_type
2 from DBA_TAB_COLS
3 where table_name = 'CRIMES'
4 /
PERSON_ID NO NUMBER
CRIMEJ3ETAILS N0 STOLEN ITEMS
SYS_NC00003$ YES VARCHAR2
SYS_NC00004$ YES VARCHAR2
SYS_NC00005$ YES DATE
SYS_NC00006$ YES DATE
SYS_NC00007$ YES NUMBER
SYS_NC00008$ YES VARCHAR2
.
177
,
: " -
?".
,
Oracle . , , -
, "
". -
- , -
, --
. -
9.2 10g ,
- : , -
, -
, --
, . ,
" ".
Oracle, -
, , -
, . ,
, .
PL/SQL-
, -
, . -
PL/SQL, -
, PL/SQL.
Oracle :
> . . -
,
%ROWTYPE, ( -
RECORD) , -
SQL- CREATE TYPE AS OBJECT;
> . . ,
: (
).
,
SQL PL/SQL.
-
. PL/SQL
,
.
178 4
Runstats
RUNSTATS',
, Web- h t t p : //
asktom. oracle. com. -
PL/SQL,
,
, -
.
, ,
.
, .. , .
-
, RUNSTATS -
, , -
, ,
. , , -
.
RUNSTATS -
"" , , ,
-
.
SQL> exec runstats_pkg.rs_start;
. -
.
SQL> exec runstats_pkg.rs_middle;
.
,
.
SQL> exec runstats_pkg.rs_stop;
, RUNSTATS .
Total Elapsed Time
Runl ran in 123 hsecs
Run2 ran in 456 hsecs
run 1 ran in 26.9% of the time
Latching / S t a t i s t i c a l differences
Runl Run2 Diff
LATCH.shared pool 12,543 39,543 27,000
LATCH.library cache 25,787 49,023 23,236
.. .
STAT.. .db block gets 4, 123 8, 432 4, 309
STAT.. .consistent gets 123, 432 354, 392 230, 960
STAT.. .physical reads 1,453 4,243 2, 790
! , -
.
, -
, ,
:
> ;
> , -
SQL, -
,
;
> -
.
-
.
, ,
PL/SQL.
Runstats
, -
( -
). ,
, SELECT
V$STATNAME, V$MYSTAT, V$LATCH V$TIMER.
SQL> create or replace view stats
1
2 as select 'S: || a.name name, b.value
3 from v$statname a, v$mystat b
4 where a.statistic! = b.statistic!
5 union all
6 select 'L:' || name, gets
7 from v$latch
. . . .
8 union all
9 select 'E:Elapsed', hsecs from v$timer;
View created.
, S:,
. , L:,
( ,
), , -
180 4
:, . -
STATS, -
, .
SQL> select * from stats;
NAME VALUE
S:logons cumulative 1
S:logons current 1
S:opened cursors cumulative 359
E:Elapsed 453411
Type created.
, STATS
:
181
declare
v_snap_id number := 0;
s stats_array := stats_array();
begin
v_snapid := v_snapid + 1;
for i in ( select * from stats) loop
s.extend;
s(s.count) := stats_line(v_snapid, i.name,i.value ) ;
end loop;
end;
PL/SQL-, RUNSTATS.
RUNSTATS,
. ,
, -
STATS ( -
). :
Name Runi Run2 Diff2 Pct2 Run3 Diff3 Pct3
:Elapsed 100 105 5 5% 120 20 20%
S:consistent gets 200 230 30 15% 250 50 25%
. .
18 diff6 int,
19 pct6 int);
20 /
Type created.
, ,
, . ( ,
, ,
, !)
.
SQL> create or replace type run_stats_output
2 as table of run_stats_line;
3 /
Type created.
, -
.
RS
RUNSTATS RS.
SQL> create or replace package rs as
2 procedure snap(reset boolean default false);
3 function display return run_stats_output ;
4 function the_stats return stats_array;
5 s stats_array := stats_array();
6 v_snapid integer := 0;
7 end;
8 /
Package created.
.
s stats_array := stats_array();
,
. -
( ), -
,
.
v_snapid integer : = 0;
-
.
procedure snap
STATS -
STATS_ARRAY. reset,
183
. -
:
snap(true);
< 1>
snap;
< 2>
snap;
..
RS
.
.
STATS
.
SQL> create or replace package body rs as
2
3 procedure snap(reset boolean default false) is
I.
4 begin
5 if reset then
6 s := stats_array() ;
7 v_snapid := 0;
8 end if;
9 v_snapid := v_snapid + 1;
10 for i in ( select * from stats) loop
11 s.extend;
12 s(s.count) := s t a t s _ l i n e (v_snapid, i . name, L v a l u e ) ;
13 end loop;
14 end;
, , , -
RESET, .
STATS s -
-.
184 4
-
, . ,
.
, , ,
PL/SQL -
.
15
16 function display return run_stats_output is
17 output run_stats_line :=
18 run_stats_line(null,
19 null,null,null,null,
20 null,null,null,null,
21 null,null,null,null,
22 null,null,null,null);
23 ret run_stats_output : = run_stats_output();
24 base_val number;
25 begin
26 for i in ( select hi.snapid, lo.name, lo.value, hi.value-lo.value amt
27 from ( select * from table(the_stats) ) lo,
28 ( select * from table(the_stats) ) hi
29 where lo.name = hi.name
30 and lo.snapid = hi.snapid -1
31 order by 2,1) loop
TABLE ()
SQL.
,
-
. ( ) -
FOR . -
, SQL- ,
, (..
).
SQL> select hi.snapid, lo.name, hi.value-lo.value amt
2 from ( select * from table(rs.the_stats) ) lo,
3 ( select * from table(rs.the_stats) ) hi
4 where lo.name = hi.name
5 and lo.snapid = hi.snapid -1
6 order by 2,1
7 /
2 E:Elapsed 2672
3 E:Elapsed 1291
2 L:cache buffers chains 49967
3 L:cache buffers chains 57323
185
( SNAPID=2) -
1 2, ..
( 1 2).
( SNAPID=3) 2 3, .. -
, ..
FOR ,
. , , SNAPID 2,
( -
).
32 case i.snapid
33 when 2 then
34 if output.tag is not null then
35 ret.extend;
36 ret (ret.count) := output;
37 end if;
38 base_val := i.amt;
39 o u t p u t . t a g := i.name;
40 output.runl := i.amt;
SNAPID, 2,
.
.
41 when 3 then
42 output.run2 := i.amt;
43 output.diff2 := i.amt - base_val;
44 output.pct2 := i.amt / greatest(base Vcil, 1) * 100;
45 when 4 then
46 output.run3 := i.amt;
47 output.diff3 := i.amt - base val;
43 output.pct3 := i.amt / greatest(base vil,l) * 100;
49 when 5 then
50 output.run4 := i.amt;
51 output.diff4 : = i.amt - base val;
52 output.pct4 := i.amt / greatest (base veil, 1) * 100;
53 when 6 then
54 output.run5 := i.amt;
55 output.diff5 := i.amt - base_val;
56 output.pct5 := i.amt / greatest (base VEil,l) * 100;
57 when 7 then
58 output.run6 := i.amt;
59 output.diff6 := i.amt - base val;
60 output.pct6 := i.amt / greatest (base Vctl,l) * 100;
61 end case;
62 end loop;
-
RET, .
186 4
63 ret.extend;
64 ret(ret.count) := output;
65 return ret;
66 end;
67
68 function the_stats return stats_array is
69 begin
70 return s;
71 end;
72
73 end;
74 /
8/ - CASE.
Oracle 9
IF-THEN-ELSE.
DISPLAY
TABLE () , THE_STATS .
RS,
1, PL/SQL-,
PL/SQL- DEPT
(REPORT_SAL_ADJUSTMENT3), ,
SQL (REPORT_SAL_ADJUSTMENT4).
SQL> exec rs.snap (true);
ORDER BY .. , , -
( 2) .
SQL> select tag, runl, run2, diff2, pct2
2 from table(rs.display)
3 where runl > 0
4 and pct2 > 0
5 order by runl
6 /
L:shared pool 37 36 -1 97
L:library cache 45 43 -2 96
L:SQL memory manager workarea 69 4 -65 6
S:recursive cpu usage 133 100 -33 75
S:CPU used by this session 229 101 -128 44
S:CPU used when call started 229 101 -128 44
E:Elapsed 234 147 -87 63
S:bytes sent via SQL*Net to cl 242 242 0 100
S:bytes received via SQL*Net f 351 351 0 100
S:buffer is not pinned count 50253 253 -50000 1
S:no work - consistent read ge 50253 253 -50000 1
S:table scan blocks gotten 50253 253 -50000 1
S:consistent gets 50261 258 -50003 1
S:session logical reads 50261 264 -49997 1
S:recursive calls 50994 491 -50503 1
S:sorts (rows) 52079 52079 0 100
S:table scan rows gotten 100500 50500 -50000 50
L:cache buffers chains 100522 913 -99609 1
, 1, , SQL -
-
( : ), -
RS .
, , , - -
-, -
(cache buffers chains)
.
. RUNSTATS
RS , PL/SQL -
, ,
SQL-.
PL/SQL
-
. ,
RUNSTATS
STATS STATSARRAY . -
188 4
,
. .
,
, -
.
, , , -
, . -
, -
,
.
,
SQL*Plus, -
2.
SRC 500 .
SQL> set autotrace traceonly statistics
SQL> set arraysize 1
SQL> set timing on
SQL> select * from SRC;
Elapsed: 00:00:35.02
Statistics
0 recursive calls
0 db block gets
83293 consistent gets
16551 physical reads
0 redo size
63311705 bytes sent via SQL*Net to client
783040 bytes received via SQL*Net from client
71153 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
142304 rows processed
Elapsed: 00:00:24.02
Statistics
0 recursive calls
0 db block gets
2
(Jonathan Lewis) .
189
.
--
. ARRAYSIZE 1, , , -
:
> ;
> , ;
> , ,
( ), ;
> (SQL*Plus).
SQL*Plus , -
. , ,
, , , -
-
, ,
.
ARRAYS IZE 1, -
ARRAYSIZE 2 - , . -
3 .
, PL/SQL .
, . 7.2,
PL/SQL, DBMS_SQL. -
, SQCPlus
DBMS_SQL, .
SQL> create or replace
2 procedure ARRAY_PROCESS is
3 s integer := dbms_sql.open_cursor;
4 nl dbms_sql.number_table;
5 d number;
6 number;
7 BEGIN
8 dbms_sql. parse (s, 'select * from S R C ,
9 DBMS_SQL.native);
10 dbms_sql.define_array(s,l,nl,500,1);
11 d := dbms_sql.execute(s);
12 loop
13 := DBMS_SQL.FETCH_ROWS(s);
14 DBMS_SQL.COLUMN_VALUE(s, 1, n1) ;
15 exit when < 500;
16 end loop;
17
18 DBMS_SQL.CLOSE_CURSOR(s);
19 END;
20 /
Procedure created.
.
SQL> create or replace
2 procedure SINGLE ROW _PROCESS is
3 begin
4 for i in ( select * from SRC ) loop
5 null;
6 end loop;
7 end;
8 /
Procedure created.
,
, -
. -
, .
.
SQL> exec single row process;
~
Elapsed: 00:00:22.02
Elapsed: 00:00:17.01
, . 5,
SQL ( -
, ..).
DBMS_SQL , -
.
PL/SQL ,
,
PL/SQL-. PL/SQL, ,
8.1 * PREFETCH
. PREFETCH
* -
, . -
8.1 PL/SQL
PL/SQL, .
-
PL/SQL. (bulk
collection). "bulking up" ( " ".
. .) ,
, , ( - -
), , -
. -
PL/SQL. PL/SQL
( ,
), .
, PL/SQL , -
, PL/SQL-.
PL/SQL, -
, Oracle 8, 9 10, -
7.3. , , , -
, , , ,
,
.
8.1,
, .
ALL_OBJECTS:
192 4
SQL> declare
2 x number;
3 begin
4 select object_id
5 into x
6 from all_objects
7 where rownum <= 1;
8 end;
9 /
500 :
SQL> declare
2 type numlist is table of number;
3 x numlist;
4 begin
5 select object__id
6 bulk collect into x
7 from all_objects
8 where rownum <= 500;
9 end;
10 /
. -
. -
REPORT_SAL_ADJUSTMENT4 1,
.
INSERT-SELECT, , ,
? , PL/SQL-,
UTL_FILE.
. -
, .
SQL> create or replace
2 directory REPORT_DIR as 'C:\TEMP';
Directory created.
Oracle 9.2 UTL_FILE
UTL_FILE_DIR -, -
. UTL_FILE
9.2 ( . "Supplied PL/SQL Packages and Types Reference").
Oracle, C:\TEMP (
)
UTL FILE DIR.
193
REPORT_SAL_ADJUSTMENT4
, . -
SQL-, -
UTL_FILE.
SQL> create or replace
2 procedure report_sal_adjustment4 is
3 f utl_file.file_type;
4 begin
5 f := utl_file.fopen('REPORT_DIR\ ' r e p o r t . d a t ' , ' W ' ) ;
6 for i in (
7 select e.empno, e.hiredate, e.sal, dept.dname,
8 case when sal > avg_sal then 'Y'
9 else 'N'
10 end status
11 from (
12 select empno, hiredate, sal, deptno,
13 avg(sal) over ( partition by deptno ) as avg_sal,
14 min(sal) over ( partition by deptno ) as min_sal
15 from emp ) e, dept
16 where e.deptno dept.deptno
17 and abs(e.sal - e.avg_sal)/e.avg_sal > 0.10 ) loop
18 utl_file.put_line(f,i.empnol|
19 i.hiredate||
20 i.sal I I
21 i.dname]|
22 i.status);
23 end loop;
24 utl_file.fclose(f);
25 end;
26 /
Procedure created.
, .
, , ,
.
CJTEMPLATE, ,
RESULTSET, .
SQL> create or replace
2 procedure report_sal_adjustment4_bulk is
3 f utl_file.file_type;
4 cursor c_template is
5 select e.empno, e.hiredate, e.sal, dept.dname,
6 case when sal > avg_sal then '
7 else 'N'
8 end status
9 from (
10 select empno, hiredate, sal, deptno,
11 avg(sal) over ( partition by deptno ) as avg_sal,
12 min(sal) over ( partition by deptno ) as min_sal
7 . 348
194 4
, ( ) ,
, -
.
16 type resultset is
17 table of c_template%rowtype;
18 r resultset;
19 begin
20 f := utl_file.fopen('REPORT_DIR', 'report.dat', 'W') ;
21 open c_template;
.
R.
22 fetch c_template
23 bulk collect into r;
24 close c_template;
, R , -
,
.
25 for i in 1 .. .count loop
26 utl_file.put_line(f,r(i).empnol|
27 r(i).hiredatel|
28 r(i).sal||
29 r(i).dnamel|
30 r(i).status);
31 end loop;
32 utl_file.fclose(f);
33 end;
34 /
Procedure created.
Windows AIX %ROWTYPE
9.2.0.1 9.2.0.2.
Metalink , 9.2.0.3.
-
? ,
RS RUNSTATS. -
.
SQL> exec rs.snap(true);
SQL- ,
.
SQL> select tag, runl, run2, diff2, pct2
2 from table(rs.display)
3 where runl > 0
4 and pct2 != 100
5 order by 2
6 /
17 -
.
(, ), .
, , -
. PL/SQL -
, .. PL/SQL- ,
. "
"
PL/SQL. PL/SQL- PL/SQL-
. SQL- PL/SQL- SQL--
. PL/SQL- -
, . 4.1.
196 4
declare
v_emp numb e r;
begin
v_erap:=73 69;
delete from emp
where empno=v_emp;
v_emp:=7468;
. 4 . 1 .
delete from emp
where empno=v_emp;
PL/SQL-
SQL-
v_emp:7210;
O
delete from emp
where empno=v_emp;
v_emp:=7340;
d e l e t e from emp
where empno=v_emp;
end;
-
5 (. " PL/SQL
, "). -
DML -
. , -
, , . 4.2.
declare
type empno_list is
table of number;
forall i in 1 ..4
delete from emp
where empno=emps(i);
end;
197
PL/SQL,
DML ,
. -
: , -
. , ,
, -
. 50000 PL/SQL-,
.
:
SQL> create table BULK_BIND_TARGET (
2 x number,
3 date,
4 z varchar2(50) );
Table created.
, , -
FOR. . -
.
SQL> declare
2 type numlist is table of number;
3 type datelist is varray(50000) of date;
4 type charlist is table of varchar2(50)
5 index by binary_inte.ger;
6
7 n numlist := numlist(};
8 d datelist := datelist ();
9 charlist;
10 begin
11 for i in 1 .. 50000 loop
12 n.extend;
13 n(i) := i;
14 d.extend;
15 d(i) := sysdate+i;
16 c(i) : = rpad(i,50);
17 end loop;
18
.
19 for i in 1 .. 50000 loop
20 insert into bulk_bind_target values (n(i), d(i), c(i));
21 end lbop;
22 end;
23 /
Elapsed: 00:00:07.03
198 4
, 7000
. -
? . -
. -
.
SQL> declare
2 type numlist is table of number;
3 type datelist is varray(50000) of date;
4 type charlist is table of varchar2(50)
5 index by binary_integer;
6
7 n numlist := numlist();
8 d datelist := datelist();
9 charlist;
10 begin
11 for i in 1 .. 50000 loop
12 n.extend;
13 n(i) := i;
14 d.extend;
15 d(i) : sysdate+i;
16 c(i) : = rpad(i,50);
17 end loop;
18
,
FOR FORALL LOOP/END LOOP. ( -
, FORALL DML,
.)
19 forall i in 1 .. 50000
20 insert into bulk_bind_target values (n(i), d(i), c(i));
21 end;
22 /
Elapsed: 00:00:01.05
50000 ! -
, . -
,
:
insert into bulk_bind_targer values( ALL n(i), ALL d(i), ALL c(l) )
. , 8 9 -
, .. ,
Oracle 10g .
, -
,
DML.
199
, 1, -
SQL, PL/SQL, .
SQL- PL/SQL- -
, .
,
. , -
, . DML
, , ,
!
, . ,
-
(.. NOT NULL), TO , -
, NULL,
.
SQL> create table MANDATORY_COL (
2 x number not null );
Table created.
10 n(37) := null;
12 forall i in 1 .. 50
13 insert into MANDATORY_COL values (n(i));
14 end;
15 /
declare
ERROR at line 1:
ORA-01400: cannot insert NULL into ("MANDATORY_COL"."X")
ORA.-06512: at line 12
, -
, .
SQL> select * from MANDATORY_COL;
no rows selected
200 4
, N (37), -
NULL. , .
, , -
, , , NULL.
9 .
SAVE EXCEPTIONS, FORALL -
, , -
, . -
, .
SQL> set serverout on
SQL> declare
2 type numlist is table of number
3 index by binary_integer;
4 n numlist;
5 begin
6 for i in 1 .. 50 loop
7 n(i) :- i;
8 end loop;
9
10 n(37) : = null; will cause a problem
11
, -
.
12 forall i in 1 .. 50 save exceptions
13 insert into MANDATORY_COL values (n(i));
14
, , -
, , ,
.
15 exception when others then
16 dbms_output.put_line('Errors:'|Isql%bulk_exceptions.count);
17 for i in 1 .. sql%bulk_exceptions.count loop
18 dbms_output.put_line('index:'|Isql%bulk_exceptions(i).error_index) ;
19 dbms_output.put_line('code:'I Isql%bulk_exceptions(i).error_code);
20 dbms_output.put_line('message:');
21 dbms_output.put_line(sqlerrm(sql%bulk_exceptions(i).error_code));
22 end loop;
23 end;
24 /
Errors: 1
index : 37
code: 1400
message:
-1400: non-ORACLE exception
1
2
3
4
36
38
...
50
?
.
,
! , -
, .
. ,
. ,
" " .
1. ( , !) -
, , .
2. ,
.
3. , .
, , , !
4. , , , ,
,
202 4
, -
.
" " , , -
, , -
.
PL/SQL.
, -
. ,
, -
. -
ALL_OBJECTS, :
SQL> create or replace
2 procedure BULK_TEST is
3 mem used number;
4 t number;
5 type recs is
6 table of ALL_OBJECTS%rowtype;
7 r recs;
8 cursor cl is select * from ALL_OBJECTS;
9 begin
10 t := dbms_utility.get_time;
11 open cl;
12 fetch cl
13 bulk collect into r;
14 close cl;
V$MYSTATS, ,
.
15 select value
16 into mem_used
17 from v$mystats
18 where name = 'session pga memory max';
19 dbms_output.put_line('- Time: 'I I (dbms_utility.get_time-t));
20 dbms_output.put_line('- Max Mem: 'I|mem_used);
21 end;
22 /
Procedure created.
, .
SQL> set serverout on
SQL> exec bulk_test
- Time: 1911
- Max Mem: 98249020
ALL_OBJECTS,
100 !
203
,
... !
LIMIT
,
"" . 8.1.6 Oracle,
LIMIT,
, . -
,
. LIMIT
. LIMITJTEST -
SRC 1, 4, 16, 64, 256,
1024, 4096 16384 . , , -
.
SQL> create or replace
2 procedure LIMITJTEST is
3 mem_used number;
4 t number;
5 type recs is
6 table of SRC%rowtype;
7 r recs;
8 cursor cl is select * from SRC
9 begin
10 for i in 0 .. 7 loop
11 t := dbms utility.get time;
12 open cl;
13 loop
14 fetch cl
15 bulk collect into r
16 limit power(2,i*2);
17 exit when cl%notfound;
18 end loop;
19 close cl;
20 select value
21 into mem_used
22 from v$mystats
23 where name = 'session pga memory max';
24 dbms_output.put_line('Rows:'IIpower (2,i*2));
25 dbms_output.put_line('- Time: 'I I (dbms_utility.get_time-t));
26 dbms output.put line('- Max Mem: 'I|mem used);
27 end loop;
28 end;
29 /
Procedure created.
204 4
-
.
SQL> exec limit test
Rows: 1
- Time: 2482
- Max Mem: 566284
Rows:4
- Time: 2065
- Max Mem: 566284
Rows:16
- Time: 1915
- Max Mem: 697892
Rows:64
- Time: 1920
- Max Mem: 936532
Rows:256
- Time: 1890
- Max Mem: 2014508
Rows:1024
- Time: 1917
- Max Mem: 5288324
Rows:4096
- Time: 1921
- Max Mem: 10372420
Rows:16384
- Time: 1885
- Max Mem: 16056916
()
exit when cursor%notfound;
end loop;
, -
. -
PL/SQL .
,
.
PL/SQL- -
.
PL/SQL-
PL/SQL -
, -
, .
, ,
PL/SQL-. ,
,
%ROWTYPE.
PL/SQL-; -
. , :
> IN ;
> OUT ;
> IN OUT " ".
,
%TYPE %ROWTYPE
, , -
, , -
%TYPE %ROWTYPE. , -
206 4
. , , -
,
%TYPE. , TEN_BYTE_COLUMN, ,
, 10 .
SQL> create table TEN_BYTE_COLUMN (
2 col varchar2(10));
Table created.
ADD_ROW -
. P_COL, -
%TYPE. ( , COL
.)
SQL> create or replace
2 procedure ADD_ROW(p_col TEN_BYTE_COLUMN.COL%TYPE) is
3 begin
4 insert into TEN_BYTE_COLUMN
5 values (p_col);
6 end;
7 /
Procedure created.
10 , .
SQL> exec add_row('0123456789');
ERROR at line 1:
ORA-01401: inserted value too large for column
ORA-06512: at "ADD_ROW", line 3
ORA-06512: at line 1
, , , ,
,
INSERT ( 3).
%TYPE -
, () .
, , ,
COL TEN_SIG_DIGITS ,
.
SQLSQL> create or replace
2 procedure ADD NUM_ROW(p col TEN SIG DIGITS.COL%TYPE) is
3 begin
207
Procedure created.
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character to number conversion
error
ORA-06512: at line 1
, 1, 3,
, PL/SQL, . -
; -
.
.
SQL> create or replace
2 procedure LOCAL_TYPE_VAR is
3 x ten_byte_column.col%type;
4 begin
5 x := '01234567890123456789';
6 end;
7 /
Procedure created.
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too
small
ORA-06512: at "LOCAL_TYPE_VAR", line 4
ORA-06512: at line 1
,
, , -
PL/SQL-,
.
, , ,
.
208 4
, , Oracle -
, ,
SQL> exec add_row(sysdate); ,
varchar2
SYSDATE VARCHAR2
.
, %TYPE :
> , () ;
> PL/SQL
.3
2, , , , -
, . %TYPE -
, , -
. , -
, :
SQL> create or replace
2 package PKG is
3 procedure ADD_ROW(p_col TEN_BYTE_COLUMN.COL%TYPE);
4 procedure ADD_NUM_ROW(p_col TEN_SIG_DIGITS.COIATYPE);
5 end;
6 /
Package created.
' , : %
not null,
( %TYPE,
not null, ).
209
17 /
NAME TYPE
PKG PACKAGE
PKG PACKAGE BODY
PKG PACKAGE
PKG PACKAGE BODY
, ,
COL , . -
, , %TYPE
.
SQL> create or replace
2 package PKG is
3 procedure ADD_ROW(p_col varchar2);
4 procedure ADD_NUM_ROW(p_col number);
5 end;
6 /
Package created.
.
SQL> s e l e c t name, type
2 from user_dependencies
3 where referenced_name in (
4 'TEN_BYTE_COLUMN',
5 'TEN_SIG_DIGITS')
6 and name like 'PKG%';
NAME TYPE
PL/SQL , ,
,
, .
, . -
REC_LIST REC.
SQL> create or replace
2 type rec is object
3 ( a number,
4 b number,
5 varchar2(30));
211
6 /
Type created.
Type created.
: SIMPLEPARM, -
, BIGPARM, -
REC_LIST.
SQL> c r e a t e or replace
procedure SIMPLE_PARM(p number) is
x number;
begin
null;
end;
Procedure created.
Procedure created.
-
50000 ,
SIMPLE_PARM BIG_PARM.
SQL> declare
2 rec_list := rec list () ;
3 tl number;
4 t2 number;
5 begin
6 x.extend(50000);
7 for i in 1 .. 50000 loop
8 x(i) := ]:ec (i, i, rpad (i, 30) )
9 end loop;
10 tl := dbms utility.get time;
11 for i in 1 .. 500000 loop
12 simple parm(i);
13 end loop;
212 4
14 t2 := dbms_utility.get_time;
15 dbms_output.put_line('Simple: 'I I ( t 2 - t l ) ) ;
16 for i in 1 .. 500000 loop
17 big_parm(x);
18 end loop;
19 tl := dbms_utility.get_time;
20 dbms_output.put_line('Collection:'||(tl-t2));
21 end;
22 /
Simple: 62
Collection: 50
! ,
, .
, , , -
. ,
.
SQL> create or replace
2 procedure SIMPLE_PARM(p number) is
3 x number;
4 begin
5 x := p;
6 end;
7 /
Procedure created.
Procedure created.
, .
SQL> declare
2 rec list := rec listO ;
3 tl number;
4 t2 number;
5 begin
6 for i in 1 . . 50000 loop
7 x.extend;
3 x(i) := rec(i,i,rpad(i,30)
9 end loop;
10 tl := dbms utility.get time;
11 for i in 1 . . 500000 loop
213
12 simple_parm(i);
13 end loop;
14 t2 := dbms_utility.get_time;
15 dbms_output.put_line('Simple: '|I(t2-tl));
16 for i in 1 .. 500000 loop
17 big_parm(x);
18 end loop;
19 tl := dbms_utility.get_time;
20 dbms_output.put_line('Collection:'|I(tl-t2));
21 end;
22 /
Simple: 97
Collection:131
, , . 500000 -
, , .
, , -
, IN OUT. , -
IN OUT. SIMPLE_PARM
BIG_PARM , -
, IN OUT.
SQL> create or replace
2 procedure SIMPLE PARM(p in out number) is
3 begin
4 null;
5 end;
6 /
Procedure created.
Procedure created.
. , -
500000 . -
, BIG_PARM , -
50!
SIMPLE_PARM 50-,
.
SQL> declare
2 rec list := rec list();
214 4
3 s number := 1;
4 tl number;
5 t2 number;
6 begin
7 for i in 1 .. 50000 loop
8 x.extend;
9 x(i) := rec(i,i,rpad(i,30)) ;
10 end loop;
11 tl := dbms_utility.get_time;
12 for i in 1 .. 50 loop
13 simple_parm(s);
14 end loop;
15 t2 := dbms_utility.get_time;
16 dbms_output.put_line('Simple: ' | I (t2-tl) ) ;
17 fo