a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 466|回复: 4

[考试辅导] Oracle中table函数的应用

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
表函数可接受查询语句或游标作为输入参数,并可输出多行数据。该函数可以平行执行,并可持续输出数据流,被称作管道式输出。应用表函数可将数据转换分阶段处理,并省去中间结果的存储和缓冲表。+ G% E1 l+ t+ h% R8 E2 A) ?2 i" a' m
  1. 用游标传递数据
. O$ b) K2 ]/ D! g1 O3 F  利用游标 REF CURSOR 可将数据集(多行记录)传递到PL/SQL函数:: e. @5 h4 |+ h3 e/ W# F% h9 I) d
  SELECT *+ ~9 b; N9 g4 r6 H+ a3 D3 n2 z4 |
  FROM TABLE (myfunction (CURSOR (SELECT *FROM mytab)));   & W9 A$ R* G4 G
  2. 利用两个实体化视图(或表)作为样板数据
& T. L4 q! ?% U* v9 U, c9 v  CREATE MATERIALIZED VIEW sum_sales_country_mv
7 g& _. \5 s; Z) k% x  BUILD IMMEDIATE4 l% M0 L) K5 d1 }3 N
  REFRESH COMPLETE3 x4 p) o6 I% [! j* I* s
  ENABLE QUERY REWRITE8 a+ ^% `( K6 M# d/ M$ r, k% u  K
  AS, u/ d( O- T9 {: t' J- L
  SELECT SUBSTR (s.calendar_month_desc, 1, 4) YEAR, c.country_id country,) T0 x5 U, V% S* ?* q3 |" R
   SUM (sum_amount_sold) sum_amount_sold- X  u. v. J" E: f1 D6 ^' A
   FROM sum_sales_month_mv s, customers c
/ G5 Z& X7 L; m* L  WHERE s.cust_id = c.cust_id
9 G4 Z1 h/ k4 R3 j6 c  AND c.country_id IN (’US’, ’UK’, ’FR’, ’ES’, ’JP’, ’AU’)! I  F& |: p, ~$ \4 k# O- M
  GROUP BY SUBSTR (s.calendar_month_desc, 1, 4), c.country_id;
: Z# f/ s; m/ K  _2 F3 l  U" ?  CREATE MATERIALIZED VIEW sum_es_gend_mv
! Z* o1 y3 f: `0 R# M5 l  BUILD DEFERRED
) E+ i, z1 s( q+ d  REFRESH FAST9 _4 d& O2 Q; g7 X$ h( |  M& \
  ENABLE QUERY REWRITE
, `& A8 q$ L  d% p# \- G7 `( l  AS# c6 n( ^- U2 q  b& a5 r
  SELECT SUBSTR (s.calendar_month_desc, 1, 4) YEAR,
: l2 f7 ?( {7 H, N" s7 i9 s- m   s.calendar_month_desc cal_month, c.cust_gender,
3 @+ e% ^. ~1 M; Y' p  a   SUM (sum_amount_sold) sum_amount_sold
3 n% `& x! b9 b; D   FROM sum_sales_month_mv s, customer c6 g) H  ]( N$ k1 W1 X8 p" X: G
  WHERE s.cust_id = c.cust_id- ?4 f) p9 u# F/ ?( Y$ n9 }
   AND c.country_id = ’ES’
; X  B2 x- t/ ^* O; _/ F   AND sunstr (s.calendar_month_desc, 1, 4) = ’2000’
$ Y; m: m* K" |9 ^, c6 J  GROUP BY SUBSTR (s.calendar_month_desc, 1, 4),
' E! y( X- \0 X1 U/ F1 G   s.calendar_month_desc,  s2 ]  {5 j5 }& C
   c.cust_gender;
回复

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:20 | 显示全部楼层

Oracle中table函数的应用

 3. 定义对象类型和基于对象类型的表类型5 ^& w2 D5 I6 J3 Y
  定义对象类型并且为进一步引用做好准备。
' w! _# y% @6 r1 G0 {9 f: F  (1)定义对象类型:TYPE sales_country_t
5 \4 z6 ]- R5 U" j: k  CREATE TYPE sales_country_t AS OBJECT (
& ^( N4 z; ~: f  z1 \5 [+ G; @  YEAR VARCHAR2 (4),
' n9 M7 L( g8 [& c% w0 x) G8 H  country CHAR (2),4 v  d2 k/ c6 w" y' z2 J
  sum_amount_sold NUMBER
. M* {9 c+ S. C: \/ |' T3 A  );
8 `0 L8 ]6 {- a8 G3 U  (2)定义表类型:TYPE SUM_SALES_COUNTRY_T_TAB
# ?! ~! h5 n0 o* m% c  CREATE TYPE sum_sales_country_t_tab AS TABLE OF sales_country_t;" `, B/ R2 t. p! {- K, k
  (3)定义对象类型:TYPE sales_gender_t
& G: `  N' g- [/ w/ p  CREATE TYPE sales_gender_t AS OBJECT (
" g' j* G3 W! K8 p/ a- O  YEAR VARCHAR2 (4),
. a4 ~# H6 m/ s3 v3 s. H  country_id CHAR (2),9 ~8 K" H/ q" W1 L5 _5 K( o$ U: ]
  cust_gender CHAR (1),# j) A- }  w% k6 Y5 s
  sum_amount_sold NUMBER
# o1 ?3 E% P( n; s) Q& n! H  );
* t4 V. z7 w6 l& p8 |5 _0 W* s  (4)定义表类型:TYPE SUM_SALES_GENDER_T_TAB
. N5 q/ w  a# w' I" I  CREATE TYPE sum_sales_gender_t_tab AS TABLE OF sales_gender_t;. _" {( \/ s8 f
  (5)定义对象类型:TYPE sales_roll_t
! z! c9 l; @+ m, ?. z  CREATE TYPE sales_roll_t AS OBJECT (
. W6 d$ P& N6 B3 B" ~# E2 G  channel_desc VARCHAR2 (20),. ~# P/ Y0 d$ d6 V+ m& L
  country_id CHAR (2),) I: C6 z/ l  s2 ^* c) r
  sum_amount_sold NUMBER" e6 `; h, P7 `" Z  |$ z' O3 G1 e
  );1 [* b8 o: k* _; c1 b
  (6)定义表类型:TYPE SUM_SALES_ROLL_T_TAB, k! S# X6 ~) \7 @  j8 {
  CREATE TYPE sum_sales_roll_t_tab AS TABLE OF sales_roll_t;
4 ~8 K# m, X. m4 I  (7)检查一下建立的类型2 c$ O9 N  }( K+ r  ^
  SELECT object_name, object_type, status8 o- ]/ u0 k+ W; ~8 ]  G
  FROM user_objects( E. r( J6 E9 X1 D# N0 y0 T1 I% f
  WHERE object_type = ’TYPE’;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:21 | 显示全部楼层

Oracle中table函数的应用

 4. 定义包:Create package and define REF CURSOR
; T  B2 h$ v0 z+ J% e  CREATE OR REPLACE PACKAGE cursor_pkg
% x4 w1 P4 }# Z2 Y, S( u4 S  IS  l/ Y% Y3 f, V, r% M3 K
  TYPE sales_country_t_rec IS RECORD (1 D1 l; K; V- s' c4 G$ J5 L
  YEAR VARCHAR (4),
7 _. ?/ j! h" M+ [% K1 d9 a  country CHAR (2),
0 r4 b& U; G; X3 A  sum_amount_sold NUMBER
. x/ N" @( h) x8 B  I# Z  );8 O, B  T3 m5 }& b7 N" q$ G5 o
  TYPE sales_gender_t_rec IS RECORD (
7 `3 i0 f* U- ]: p  ?+ ^" D  YEAR VARCHAR2 (4),
8 S# E4 j- K# s' @  country_id CHAR (2),
$ i3 o  u0 [! }5 P3 D( R1 n  cust_gender CHAR (1),
8 f# t0 r$ \. V. X& ]9 ^4 h  sum_amount_sold NUMBER6 ~+ g/ A* |; L: B) C
  );; x. g: T; s* {! I) g/ Y8 j9 V
  TYPE sales_roll_t_rec IS RECORD (* y; ^, {. G6 V
  channel_desc VARCHAR2 (20),
3 d3 B: q0 C, A  country_id CHAR (2),* P" ]) n; V( m+ d% g9 k4 h
  sum_amount_sold NUMBER9 }0 _5 ]' p( Y6 W& y. x& O) Z* I9 S
  );
7 [# W* [& H0 z, ~; \  TYPE sales_country_t_rectab IS TABLE OF sales_country_t_rec;
2 K; }( g0 m* X4 F4 `. q  TYPE sales_roll_t_rectab IS TABLE OF sales_roll_t_rec;
# T! N" C! \- n% S6 U  TYPE strong_refcur_t IS REF CURSOR
5 d! y5 `6 J3 B" B4 U7 o  RETURN sales_country_t_rec;! I* {2 o+ L0 U6 t- v+ n7 _/ e
  TYPE row_refcur_t IS REF CURSOR
1 {& j6 K" [8 e2 i+ \$ u: q  RETURN sum_sales_country_mv%ROWTYPE;
* O8 z: L' q% \* f* L. D, l  m  TYPE roll_refcur_t IS REF CURSOR8 y+ [4 N4 l& Q$ p: C
  RETURN sales_roll_t_rec;1 G4 n, N6 R# R$ w: @' L
  TYPE refcur_t IS REF CURSOR;" t$ D; `$ G% W) |: @
  END corsor_pkg;
' c# T  ]. {1 s6 z! v$ u
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:22 | 显示全部楼层

Oracle中table函数的应用

5. 定义表函数
; t' A+ q7 n( G6 e1 t. H+ ^/ v- K' T% `# I  (1)定义表函数:FUNCTION Table_Ref_Cur_Week
. }8 X+ Q8 W* k  CREATE OR REPLACE FUNCTION table_ref_cur_week (cur CURSOR.refcur_t)
7 u- n* Q/ Y# @& e  RETURN sum_sales_country_t_tab! ]) a4 C% W# \) m. i: U
  IS
. `# S1 f2 @9 v: k2 V9 ~  n9 E  YEAR VARCHAR (4);* }7 y% d  j* C0 K! B, p5 I; r
  country CHAR (2);  g5 a: r) W& d0 N5 D2 a! c6 n
  sum_amount_sold NUMBER;
2 B$ I2 a" O, y- P1 D9 T, r  objset sum_sales_country_t_tab := sum_sales_country_t_tab ();- H# _: n8 @+ v0 M- I
  i NUMBER := 0;
9 [5 G9 q- o/ j8 T6 E, h  BEGIN
* h1 A. x! }) W  LOOP, l8 q( k8 p8 J& a4 W+ p' g) v
  -- Fetch from cursor variable
" I+ ]8 `+ g7 B2 N6 h) E. \' @  FETCH cur
, n& A6 w- ]- B; G8 M; e  s2 g; k   INTO YEAR, country, sum_amount_sold;
: h+ i% e2 l8 d2 J5 k5 E" f  EXIT WHEN cur%NOTFOUND;
4 B3 x+ G# p9 x6 l0 ^8 B9 q3 y   -- exit when last row is fetched
% T7 ]( D4 W  }9 C+ v0 p+ W  -- append to collection
9 y' B  A( x3 q% a- @  p5 x# ~  i := i + 1;* |- E; q, Z( Q3 [3 `  w* U
  objset.EXTEND;  Z* Z1 `: f, N
  objset (i) := sales_country_t (YEAR, country, sum_amount_sold);( ?! w2 w+ J" D/ ?, X4 B) n9 g; l5 S
  END LOOP;2 K& E2 |, N# y: _3 S( S: T6 i. O
  CLOSE cur;+ _' {9 @2 N9 p1 X! `  A3 ~
  RETURN objset;
2 N0 `! H, b8 t  Y  END;
7 k, r9 X  C. [; {  /
0 P: r2 K8 D9 S+ s  (2)定义表函数:FUNCTION Table_Ref_Cur_Strong
' m5 }* z6 V' D" ~. h: @4 B' Z  CREATE OR REPLACE FUNCTION table_ref_cur_strong (cur cursor_pkg.strong_refcur_t)
! l# \4 l  a, y8 v3 R  RETURN sum_sales_country_t_tab PIPELINED$ G$ E+ e8 ?* r& a9 X0 ^# o
  IS
  o! [1 f' Y( y/ ?- o  YEAR VARCHAR (4);( ]8 |4 F8 k, Y, s8 G; b! F
  country CHAR (2);
! `$ G: E# |. ~9 P7 Z5 L, T  sum_amount_sold NUMBER;
1 `! |% s' b5 D' {9 H  i NUMBER := 0;
& O9 s# p& ~: C1 ]& p4 Y  BEGIN& |2 v$ p- y) S% @1 |
  LOOP- j. Q5 ~& \1 W# p( Y# K' ?5 F- ^
  FETCH cur- w) b. ?, b$ v0 Q- ?
   INTO YEAR, country, sum_amount_sold;- m8 N, j5 @4 K% b! ^! G, f
  EXIT WHEN cur%NOTFOUND; -- exit when last row fetched* O8 J0 Q2 ^; R) G
  PIPE ROW (sales_country_t (YEAR, country, sum_amount_sold));
2 P4 E* {8 e$ o& p  END LOOP;
8 \: k% Z! b. Z' D  CLOSE cur;
$ e/ j; k& x* c) R* w0 O  e6 ?  RETURN;+ m2 k( `4 b% ]3 p& \9 L: m
  END;+ ?& J( p) |. t* v$ {
  /
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:23 | 显示全部楼层

Oracle中table函数的应用

(3)定义表函数:FUNCTION Table_Ref_Cur_row
0 o# K) w2 E3 F/ c% y4 |* a( p& Z  CREATE OR REPLACE FUNCTION table_ref_cur_row (cur cursor_pkg.row_refcur_t)
7 g4 P1 `) ~: r6 h5 F: Y1 e% q# H* L  RETURN sum_sales_country_t_tab PIPELINED4 i3 v. m% f8 ]7 @" L0 d
  IS9 ?, ]! J% e/ Z" H1 p) X
  in_rec cur%ROWTYPE;
0 a% c/ K9 }( O9 u2 C7 G( Y  out_rec sales_country_t := sales_country_t (NULL, NULL, NULL);3 Y* t1 S& ~& V3 l4 h+ v4 Z
  BEGIN
; d0 z9 e# l' H! W% x  LOOP
# }7 O- r; d) Y7 \& t" l+ u. i  FETCH cur
7 B. M  u9 g, S5 [3 L   INTO in_rec;
. Y% t4 J. E/ o) x% u  EXIT WHEN cur%NOTFOUND; -- exit when last row is fetched- W5 ]" X* _1 x. H& r
  out_rec.YEAR := in_rec.YEAR;& m% Y6 }& |( C# W" j9 L
  out_rec.country := in_rec.country;0 a! |- D4 c, K( r! R: V" \8 A
  out_rec.sum_amount_sold := in_rec.sum_amount_sold;
* h( @( o# |. B% ]& G  PIPE ROW (out_rec);
8 A9 i: W. @, F0 n9 J7 E  END LOOP;
" f, A; l6 e' |3 }- R$ J  E  CLOSE cur;
. ?$ t5 R' J/ z( y9 `8 q4 ?  RETURN;
$ X' P; j7 B# X, U  END;
. g1 g! x2 b: N& m/ R& a2 I; v  /: n! L, J9 X1 {: f, n
  (4)定义表函数:FUNCTION Gender_Table_Ref_Cur_Week( l8 A/ o/ V/ m; N/ }9 u6 N1 Z4 ^& h
  CREATE OR REPLACE FUNCTION gender_table_ref_cur_week (cur cursor_pkg.refcur_t)* w7 f8 Z& w, w" @! w/ a" O
  RETURN sum_sales_gender_t_tab
, u/ e9 n5 \4 m. P  IS0 T' k, F! Q0 B$ `
  YEAR VARCHAR2 (4);# O0 v8 g8 M, P# x- [, A
  country_id CHAR (2);
1 E. h2 O* J) J7 @3 t4 D9 g5 y+ ]  cust_gender CHAR (1);
  I3 X$ \' H) g  o) Y/ b1 v+ ^7 J  sum_amount_sold NUMBER;0 G( j- ^) P( n2 P6 h
  objset sum_sales_gender_t_tab := sum_sales_gender_t_tab ();0 [& o( a/ V! P/ z. @
  i NUMBER := 0;2 w# D1 S1 n. S
  BEGIN0 Q" j/ J5 M  y) _  X5 Q  s
  LOOP
) W  T# ~1 s. O4 R% E0 q  FETCH cur
# E* V" c* m6 u# i# D% M   INTO YEAR, country_id, cust_gender, sum_amount_sold;* G. v) }" N  b( z  A2 B( p
  EXIT WHEN cur%NOTFOUND; -- exit when last row is fetched! v) I1 z0 ]6 w" E* V- X; U" x
  i := i + 1;
; W& o8 ~  ?  ~( r0 ]8 M# e  objset.EXTEND;
9 ?3 T# Q+ [* K: Q6 z  objset (i) :=
6 L! D0 _$ d# C1 J& Y8 x   sum_sales_gender_t (YEAR, country_id, cust_gender, sum_amount_sold);
3 ]* k0 l& ^' T+ F+ z  END LOOP;
9 J; P& X5 m' ]- N) Q. t: Z, f; F7 w9 W7 y  CLOSE cur;
& x6 z4 k$ }& \" j& G5 d  RETURN objset;  F8 ~" r5 U2 {% I/ |: Z) v  j: B' U
  END;
. o* R, {6 P3 G) S# N8 s  /! z. U6 r4 V# x  b  B6 L. r, ?! Z
  6. 调用表函数
* |; u1 _- S$ z: D( F  下列 SQL 查询语句调用已被定义的表函数。# F) O% Q, J% Q* `3 U
  SELECT *FROM TABLE (table_ref_cur_week (CURSOR (SELECT * OM sum_sales_country_mv)));
5 m: R9 s1 ]/ S4 D  SELECT *FROM TABLE (table_ref_cur_strong (CURSOR (SELECT * FROM sum_sales_country_mv)));$ W2 o. ~6 v% G) o- z
  SELECT *FROM TABLE (table_ref_cur_row (CURSOR (SELECT * FROM sum_sales_country_mv)));
( ~1 ^7 J! a8 G; q: }0 g  SELECT *FROM TABLE (table_ref_cur_week (CURSOR (SELECT * FROM sum_sales_country_mv WHERE country = ’AU’)));
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-21 13:43 , Processed in 0.182057 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表