a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 239|回复: 2

[考试辅导] Oracle9i的1467错误解决方法

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
在使用自定义聚集函数时出现了一个ORA-1467错误。  - C! ?& J+ l3 B- F

+ m5 p* u7 J0 o- D% m$ x" l. \' b" M) I0 q/ K% V- h1 V
根据Oracle文档上的描述,1467错误是由于排序的键值超过了DB_BLOCK_SIZE。  
+ @( B1 ^; s3 _但是出现错误的SQL似乎并不满足这个条件。下面简单构造这个错误:  
# \0 q) H- V& w3 o# @SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (   # ^/ ]5 ~( y2 v: f) w8 q  ~
2 STR VARCHAR2(30000),   ' o, }" B: @- n- w
3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER,   
8 I* Y# b6 Y7 o4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,   
: S$ S9 O6 A2 n- W5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER,   + [* A% h, k( R
6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER   # V3 e, s! e" F  d* r
7 )  9 E, R$ k" N) _8 T
8 /  7 g2 M$ |0 n" c' y& \
Type created.    K: \3 c# W% U+ p9 X" i
SQL> CREATE OR REPLACE TYPE BODY T_LINK IS   
' G6 R1 p1 |( ^! `2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER IS   
+ V! I! x7 M* Y0 j- @6 n3 BEGIN   - e0 N2 Z) c7 M- g8 ?2 t  A& X
4 SCTX := T_LINK(NULL);   
# n# C. ^. _) p0 c( g* p$ V' z! G9 E5 RETURN ODCICONST.SUCCESS;   
" z! x% C- R3 o/ B# M+ m6 END;   ; M5 K; K. F/ d" w* I2 ^  d2 l
7   6 w: D! u& I, {* u- x8 G
8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS   
5 J; N! Z, {$ ?# i4 m; f- w9 BEGIN   * z6 `1 V' ^6 O
10 SELF.STR := SELF.STR || VALUE || ’,’;   
: s$ S! w: |3 C. ?7 ~: \11 RETURN ODCICONST.SUCCESS;   
. F8 z  O( n( _( {) {12 END;   
3 d7 h7 A2 c4 R. ~7 s13   
) }: _$ Y5 k' ~1 ~14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS   ( f& K/ m' @7 D" ]5 X7 J& B
15 BEGIN   
$ E1 m- ^3 r$ W* x16 RETURNVALUE := SUBSTR(SELF.STR, 1, LENGTH(SELF.STR) - 1);   
2 `1 x1 R+ Y, I8 U/ O5 ^( J17 RETURN ODCICONST.SUCCESS;  9 P8 y4 n% I1 c8 z# I: N: [6 l: C
18 END;   
9 w/ j2 e* [/ P! a  q0 W  h19   
% L) \* ?+ E6 L7 O1 g20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS   8 z, T  G5 \+ n$ b8 g
21 BEGIN   9 R6 Y+ x: z. p- u- d. h( x' [- J
22 NULL;  5 t. {+ S! N" G! y  [4 v0 ?) X+ S
23 RETURN ODCICONST.SUCCESS;
回复

使用道具 举报

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

Oracle9i的1467错误解决方法

24 END;  & I, }0 ?) \( R1 h" X8 s0 D
25 END;  ( h  o& O( y8 N( ]# z" |1 J
26 /  7 B- `7 K. h; Z, S: f1 i  q
Type body created.  - B" o4 R! E  n6 h1 [
SQL> CREATE OR REPLACE FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2   & D6 p6 ?5 a, R4 q
2 AGGREGATE USING T_LINK;   
8 ?; L. P8 o, r9 A( ?8 {) j; e4 X3 /  1 G1 L1 p' ?% p9 V
Function created.  " y% H0 [% f6 B7 {2 w
SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS;  
% _4 O' `( V% K/ D! qTable created.  7 N2 [4 l# O0 w
SQL> SELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  ) Q6 y+ o+ @# [3 C: |/ ]
2 FROM T  6 J& Y6 j4 R: w; _, b: I1 a0 g
3 GROUP BY OWNER;  
: C! s0 x& p  A* z' M2 O5 LSELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  
7 A% B. _  s/ v*  
4 h! l. L. i' w, b4 w9 GERROR at line 1:  & G. W  c6 \) z
ORA-01467: sort key too long  
: ~" [5 [0 b+ H; |2 ASQL> DESC T  ! p" n& E9 z4 `% S2 n
Name Null? Type  
1 Q( R7 s1 n, q: A0 x: {' Z' ?--------------------------------- -------- --------------  
' V' K7 v* F( E+ i4 TOWNER VARCHAR2(30)  
: e3 L. X& T' qOBJECT_NAME VARCHAR2(128)  
' J% d" m8 m3 V3 M+ USUBOBJECT_NAME VARCHAR2(30)  
7 `" n. I: ?9 K* _% [OBJECT_ID NUMBER  
. J$ R2 P& V8 ]6 \. c# fDATA_OBJECT_ID NUMBER  
* t6 C# @; M& o* l! s4 kOBJECT_TYPE VARCHAR2(18)  
' n- ~- B& }, g2 p/ ]# r5 o, |1 pCREATED DATE  2 I" O) \- l! [. d+ ~5 L- u
LAST_DDL_TIME DATE  $ U7 k' A9 W3 @7 u2 Z
TIMESTAMP VARCHAR2(19)  ! w0 e, R2 W/ e! {  f3 o
STATUS VARCHAR2(7)  8 C/ a$ O: S% e* d) y
TEMPORARY VARCHAR2(1)  ' k8 A; K9 }. C, k/ I& F
GENERATED VARCHAR2(1)  
" ^2 h& W! Z9 J6 t! K- h  K+ _5 ^& ~SECONDARY VARCHAR2(1)  
  p+ D! x0 e; r. \7 d. q2 {' fOWNER列的长度只有30,而且即使换成长度为1的列也没有作用。  3 {1 h, x5 h- [; t
SQL> SELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  7 r0 y% H, b! ]$ {% K4 e3 R
2 FROM T  % K  _) n3 D7 {2 f
3 GROUP BY TEMPORARY;  
- a' ?& J( Q! {" i8 D) F" h# G7 ASELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  
& b8 [5 e" `8 i% B2 W# ]*  ) `6 {4 \0 ?" w# B0 c% \
ERROR at line 1:  + g9 p1 T" g6 S4 m. J$ z% ?
ORA-01467: sort key too long  
- F, e- [6 h$ \5 _  Q既然和GROUP BY列没有太大的关系,那么是否与F_LINK输入列的长度有关:  5 v$ v' w5 C" b2 n2 T
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
% ]2 }' K# g' X6 G9 A2 FROM T  
/ f5 V* ?2 O7 E9 U8 N  l/ U- Q3 GROUP BY OWNER;  7 h) y4 f) d9 l
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
8 k- `+ `$ |4 g+ m& \# F$ Z) w*  
: U2 |/ \  P  lERROR at line 1:  
" E7 C  |! P4 A3 \ORA-01467: sort key too long  
4 u+ Z+ [7 x, Y$ D) P4 z即使将F_LINK的输入参数变成常数1、2、3,问题仍然会出现,看来和F_LINK输入参数的长度也没有关系。  ( c6 P, H0 [, R8 u
虽然与F_LINK输入参数长度没有关系,但是和F_LINK函数调用次数有关,将F_LINK三次调用变为两次调用,就可以得到结果:  
  c4 o" \4 V2 s4 X. rSQL> SELECT OWNER, F_LINK(1), F_LINK(2)  $ X1 i! G: ]3 o4 P0 x  u8 F
2 FROM T  
; S' O* c* ^  ~$ \$ d3 WHERE ROWNUM < 10  
4 Y0 G; F; x6 V% T* I8 E4 GROUP BY OWNER;  ) `" O6 e! C1 R) g3 _8 K
OWNER F_LINK(1) F_LINK(2)  & X3 j4 |6 p5 x- f: p! ~$ j+ f# P" u
------------------------------ ------------------------------ -----------------  + a& @) |+ ~- P; u1 z- ^
SYS 1,1,1,1,1,1,1,1,1 2,2,2,2,2,2,2,2,2  
- E: H' _  O" c! ^+ ?这个问题在9i上就会出现,而且与DB_BLOCK_SIZE的大小没有关系。在DB_BLOCK_SIZE为8K和16K的环境下测试,得到的结果完全一样。  
( y& K0 o' t5 D) JSQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;  2 j' j' a; `) `( U# g9 u
Table created.  
" \/ |( Z/ z) f1 zSQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
0 @3 ]$ Z% U. O! D+ [! @2 FROM T   
, F8 q, @/ j; f2 F& \% Z. M3 GROUP BY OWNER;  
. A; U+ T& f8 F4 P, y; c/ L  XSELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  2 v3 O* Q  D: k0 e4 x- m! @: r2 _
*  ; y% r7 r; l  h3 j& d: K- c
ERROR at line 1:  
3 l( G3 d+ g7 @( b$ q; ^ORA-01467: sort key too long  
0 \8 ]$ w' F3 L& y0 ~& N
  b5 X. _/ R) H( RSQL> SET SERVEROUT ON  % F& b9 {% P/ u: b1 W% s3 L* \
SQL> DECLARE  
( N# Y* |; A% G0 s: _2 h$ U2 V_NUMBER NUMBER;  ' e" E" q$ I' Q, Z
3 V_STR VARCHAR2(4000);
回复 支持 反对

使用道具 举报

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

Oracle9i的1467错误解决方法

4 V_RES NUMBER;  
- m+ k0 o# [0 {0 G- E5 BEGIN  
0 J  v3 T1 ]6 F* |+ ^/ f) Y6 V_RES := DBMS_UTILITY.GET_PARAMETER_VALUE(’db_block_size’, V_NUMBER, V_STR);  7 v, z7 a! r2 q) I: O- B* h
7 DBMS_OUTPUT.PUT_LINE(V_NUMBER);  
9 b: V$ H5 l, K8 u8 END;  : b4 I: h. ^' O$ y0 G
9 /  3 T9 o3 G$ I# S* M0 ~) ~5 i
8192  
* p- ]/ V6 @5 G- O. T5 LPL/SQL procedure successfully completed.  & i6 |, s5 T1 n3 l5 [, m
SQL> CONN TEST@GPODB  1 H* U% x7 y5 G( H, u8 z8 {, U
Enter password:   . `$ K& e; I* D% O2 |# _8 v, n1 Z
Connected.  
) t/ t1 z2 B7 G) g. v" a. SSQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)   2 `- N. E1 S0 a& g* G
2 FROM T   1 o9 D+ I% V. V2 B, X- Q' ~
3 GROUP BY OWNER;  " L. _+ F5 t4 B! G  E' @% W
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
; b1 p( ], Z$ A7 d$ u1 \*  
: {9 T* z8 O4 j& {ERROR at line 1:  7 U; K9 I9 J' X4 E
ORA-01467: sort key too long  4 R( {9 F" n* ]* M( i

4 J" C6 W8 |% x& ~' a' g1 USQL> SHOW PARAMETER DB_BLOCK_SIZE  ( l8 {6 f7 t4 h
NAME TYPE VALUE  
% c6 `, W4 y  N8 T0 x6 r( d------------------------------------ ----------- ------------------------------  0 b: M2 X  c( }/ L1 r7 ]4 K
db_block_size integer 16384  
! Q; ?  V3 F; Y# G6 D而这个问题在10g已经得到了解决,测试发现即使有30多个F_LINK的调用,也没有出现ORA-1467错误。  2 d' U. Y5 P9 `% f0 ?/ I
SQL> CONN YANGTK/YANGTK@YTK已连接。  4 F' r1 |: o! h7 f$ h# J
SQL> SELECT * FROM V$VERSION;  ! e3 d% T( q8 J, s+ A5 z
BANNER  . x) i4 Q' U( B" ^7 e  [
----------------------------------------------------------------  . w4 w  S" ?& l) y
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod  
' F8 I, g2 u2 W( O, X  WPL/SQL Release 10.2.0.1.0 - Production  5 n7 x* c$ y0 ~. t& z0 a. q
CORE 10.2.0.1.0 Production  
7 a( D4 G3 ^9 _$ Y; v$ X* F4 ]TNS for 32-bit Windows: Version 10.2.0.1.0 - Production  
4 [, L% z/ Y3 |. ?/ t6 W' aNLSRTL Version 10.2.0.1.0 - Production  
" z8 f+ U* Q& x# K& gSQL> COL F_LINK(1) FORMAT A20  % d. s3 i; s2 ^' g9 K0 U$ o) h
SQL> COL F_LINK(2) FORMAT A20  7 c8 @, E/ ~0 D  \1 M- Y0 _
SQL> COL F_LINK(3) FORMAT A20  / N. N2 C. L7 k. K6 U7 O& B
SQL> COL F_LINK(4) FORMAT A20  
( M- O) p4 B1 \* z6 d2 N3 MSQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3), F_LINK(4)  
  d5 H! ~, A% ]" G7 o  l2 FROM T  + ^' O. `. u* k! i: k% ?
3 WHERE ROWNUM < 5    U8 G7 v0 e0 @5 G* I; u
4 GROUP BY OWNER;  - G) _8 q$ d2 I2 w, `7 Z) J& Z. M
OWNER F_LINK(1) F_LINK(2) F_LINK(3) F_LINK(4)  0 U- [9 ^3 Z1 N( b
-------------------- -------------------- -------------------- -------------------- ------  - I/ @; |9 m) X! N1 Y0 f  [
SYS 1,1,1,1 2,2,2,2 3,3,3,3 4,4,4,4  3 l1 u! s  i7 c8 X  d( ?! w
在9i上如果碰到这个问题,可以考虑使用变通的方法解决。比如使用CONNECT BY语句来代替自定义聚集函数。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 06:35 , Processed in 0.215223 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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