a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 219|回复: 2

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

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
在使用自定义聚集函数时出现了一个ORA-1467错误。  
) V, @# }' B$ d3 a! ~4 `! y$ `# S4 E7 `+ L+ r7 Q' K% ^6 ^; ]
8 I8 Q0 _9 h3 f* h: q7 r( d
根据Oracle文档上的描述,1467错误是由于排序的键值超过了DB_BLOCK_SIZE。  
3 j! `' b" `8 N# j$ W: }但是出现错误的SQL似乎并不满足这个条件。下面简单构造这个错误:  % t) o; M4 k$ a0 ?9 |7 T9 I. Y
SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (   
9 J& o- U7 y# R7 j+ A  r2 STR VARCHAR2(30000),   
  z: P% q! E( O; ~9 h3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER,   
4 O" J" i5 K- g! F. w4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,   7 z) [& k" p" w
5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER,   $ U8 G0 X# N0 @; g: ^6 c; Q
6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER   
: c0 J  \& g$ q6 |, M& u7 )  0 O+ X: ]$ b- [6 H( Q8 d3 e
8 /  6 L3 P+ C: `! B9 b0 W- p
Type created.  0 e4 S& a9 Y$ c; ?% _
SQL> CREATE OR REPLACE TYPE BODY T_LINK IS   
5 j0 ^+ l0 {$ p- ?4 ?2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER IS   $ o/ j2 I2 P# s( w: T0 O
3 BEGIN   # C$ p) b# @: O( u
4 SCTX := T_LINK(NULL);   
: h; W6 r" k( C+ w" ?' J# e) m4 `% o; j5 RETURN ODCICONST.SUCCESS;   4 p2 L7 J0 S' x! v% |
6 END;   
  P2 w" h7 K7 Y4 k  T3 b+ f/ y3 y5 z7 f7   
- \7 J7 Z  _) T( E- W8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS   8 N" a; I% [. {8 ^" V2 Q
9 BEGIN   * |+ I7 @% G: W0 J
10 SELF.STR := SELF.STR || VALUE || ’,’;   
" N2 W$ h6 C# N3 F/ W* H" u: k11 RETURN ODCICONST.SUCCESS;   * z# s0 U& {8 ^! b) j
12 END;   
: X" U3 v% Z$ k. ^: p13   
9 Q7 f; n# }3 P) @" Q$ F) G14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS   
2 L3 h( G% s" h( N8 q/ ]15 BEGIN   
$ A& D' F, H! F16 RETURNVALUE := SUBSTR(SELF.STR, 1, LENGTH(SELF.STR) - 1);   
4 t  U2 [2 ~- N7 t0 H17 RETURN ODCICONST.SUCCESS;  . r( v6 P" ?7 A7 J4 J6 _9 Y; v/ f
18 END;   , q$ U8 j" M: D1 y: {4 w; M* W1 A
19   
+ Q# N2 _# W$ C20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS   
; ?/ ]; h# j1 L# K21 BEGIN   2 P, j) {3 [$ u
22 NULL;  
6 ~1 F- ^% J) {2 Z5 J3 f23 RETURN ODCICONST.SUCCESS;
回复

使用道具 举报

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

Oracle9i的1467错误解决方法

24 END;  
3 u1 X' o2 b' x, u25 END;  
% t0 {6 n) P$ f. `* F  K% _5 {6 n5 `26 /  3 a  A* m! U" i$ a+ Q$ P
Type body created.  
4 n( L. l, O+ X, `2 I9 N- p4 h) gSQL> CREATE OR REPLACE FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2   
6 h$ Z; R. C# V6 D5 z7 P2 AGGREGATE USING T_LINK;   
' ~$ s$ Y3 ?9 x' H, O3 /  2 P! ?- J5 o5 F  B, Q8 x0 x. w% Q; x
Function created.  
8 ~& F4 y. \0 E* H: r( V/ ~1 tSQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS;  
. {, E( J/ n  q/ z: b* u4 Z- h3 `Table created.  
; Y! M8 H$ A; b$ ySQL> SELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  4 b% @( X0 M) a- K& X4 Y
2 FROM T    j7 p5 p* _+ ?  b, M
3 GROUP BY OWNER;  
3 _) |' K  J- y* }SELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  4 q5 C: W; a# m9 p
*  3 ^5 U" ]' u8 p# P) W
ERROR at line 1:  
& |, V: y  l( G; q4 MORA-01467: sort key too long  ; W' p  V& f0 m' e
SQL> DESC T  
% T2 u) e3 ]$ n* \6 `Name Null? Type  
( J  c' D) w8 X& t--------------------------------- -------- --------------  4 |6 B7 T+ _' E: G* N
OWNER VARCHAR2(30)  0 w0 W5 `( |" |7 g" l
OBJECT_NAME VARCHAR2(128)  2 s4 {8 e6 i5 A, ]: e
SUBOBJECT_NAME VARCHAR2(30)  # p; S+ |& C# |5 A" ]! T2 \  X
OBJECT_ID NUMBER  ; u" T3 C& S0 ^/ l6 `  z8 [
DATA_OBJECT_ID NUMBER  ; ~& |- I% s. x8 o; X( B; L
OBJECT_TYPE VARCHAR2(18)  
4 A8 X' w3 ]" g# }CREATED DATE  
, H2 C, z8 s7 `1 CLAST_DDL_TIME DATE  
# G4 @, _9 o  oTIMESTAMP VARCHAR2(19)  1 n) J* o% D3 z
STATUS VARCHAR2(7)  
; a3 x* E6 R; X. a1 B! WTEMPORARY VARCHAR2(1)  " i8 q2 ^$ k' J% M3 R) H) h! B; X
GENERATED VARCHAR2(1)  
" u+ s& ^, m' a/ G! m$ ?  CSECONDARY VARCHAR2(1)  1 Y9 J& S2 S9 S4 ^$ h
OWNER列的长度只有30,而且即使换成长度为1的列也没有作用。  
  d1 O5 B* J! {SQL> SELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  ' |, H" Z* P" F2 i" c% \: O: |) S
2 FROM T  
6 V8 P6 k7 A) s3 Y; [, o" b3 GROUP BY TEMPORARY;  ; |  ~, l! V: @4 y
SELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)  ( y4 d- F3 ~" J7 L
*  
; M/ D/ a+ a" Q& U7 CERROR at line 1:  
* y, f6 I4 O2 zORA-01467: sort key too long  
2 r4 H0 e. F$ o既然和GROUP BY列没有太大的关系,那么是否与F_LINK输入列的长度有关:  7 j% T7 I. D1 [7 ]7 |* V, A1 x8 W- A
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  : Z3 o! M6 {  I- I  U4 Y" R. r% V& g
2 FROM T    Y( `  p6 i9 U1 @& Z1 A/ k
3 GROUP BY OWNER;  + Q8 s: a) s- ~+ n( ^
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)    p: N9 e4 ]4 D/ l" E
*  " g9 n8 C% ?; s/ R' V+ g
ERROR at line 1:  
5 B& r# l8 H' B9 v3 dORA-01467: sort key too long  
6 ~) |! @  T4 i) e# r6 l2 |( M即使将F_LINK的输入参数变成常数1、2、3,问题仍然会出现,看来和F_LINK输入参数的长度也没有关系。  
/ Q+ ^% C( a1 ?2 V+ B3 g  S; v$ H虽然与F_LINK输入参数长度没有关系,但是和F_LINK函数调用次数有关,将F_LINK三次调用变为两次调用,就可以得到结果:  
- H% b1 Z6 i& }7 ~# M# HSQL> SELECT OWNER, F_LINK(1), F_LINK(2)  # Z% A- p6 g" F- y+ O+ F
2 FROM T  ) v6 T* g0 Q/ U
3 WHERE ROWNUM < 10  
' D2 m5 ?' ]  E/ ?4 ~4 GROUP BY OWNER;  
, u- x2 K! j# ~' |, {/ V# V9 WOWNER F_LINK(1) F_LINK(2)  * N  p1 t" n+ v* {2 x% u% }
------------------------------ ------------------------------ -----------------  
1 p  P& J& j5 b0 v, j, F  Y# ZSYS 1,1,1,1,1,1,1,1,1 2,2,2,2,2,2,2,2,2  
  p" H' m. D4 c9 @; O$ M4 g( m这个问题在9i上就会出现,而且与DB_BLOCK_SIZE的大小没有关系。在DB_BLOCK_SIZE为8K和16K的环境下测试,得到的结果完全一样。  
3 m$ b4 `( Y3 g1 }$ {5 R) M! n2 YSQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;  : i6 j/ _  c7 b
Table created.  1 q- T8 Y$ b" b8 M" q
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
% V+ Z9 ]4 `# X: \$ u3 [4 n: T% H2 FROM T   
8 K4 B3 G  y& p5 n% j6 p; N3 GROUP BY OWNER;  
6 ?: C# @: ?/ bSELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  6 C2 v6 ], x6 w5 T6 \: M
*  
8 O" R2 J% t2 i5 S0 ~/ W: ?) qERROR at line 1:  
4 m9 l! B# U8 b2 QORA-01467: sort key too long  
! ~& m  W) l5 C
( [  p9 B) |8 F8 i+ ^6 B! p5 FSQL> SET SERVEROUT ON  
- l! g9 ~7 C- y4 Z- gSQL> DECLARE  ! m( t- {* ]" n& D/ ^# b* v
2 V_NUMBER NUMBER;  1 n1 F* W' x0 {# M
3 V_STR VARCHAR2(4000);
回复 支持 反对

使用道具 举报

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

Oracle9i的1467错误解决方法

4 V_RES NUMBER;  
. @* W; m- j* ?# X! B5 BEGIN  
9 R& e+ |4 }5 [& J3 E. h6 V_RES := DBMS_UTILITY.GET_PARAMETER_VALUE(’db_block_size’, V_NUMBER, V_STR);  
+ A! v( k' l( {2 r! c% @5 ?7 DBMS_OUTPUT.PUT_LINE(V_NUMBER);  
7 j- R, Q3 c1 H" \# k, |- S8 END;  9 o3 L2 E0 j* h& V& X% r* D% B8 i
9 /  
- a7 b* S! _% `% s! M) |8192  
" G& I, L& q0 a2 n9 I0 XPL/SQL procedure successfully completed.  7 F/ K5 w7 j4 N  R( j/ G, }- r2 D  x
SQL> CONN TEST@GPODB  
! F! `& y0 R) X& r0 cEnter password:   0 {2 @+ ^  C/ Q* h
Connected.  - z3 _  @0 J4 ]8 d5 U
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)   
6 H% s/ f) p) ]$ |$ H3 F5 |2 FROM T   
9 s# w8 X( y9 V+ W5 q, D6 r* }3 GROUP BY OWNER;  
$ X. [6 X5 W/ V) f: y# cSELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)  
) s( N6 Y5 y& b6 O/ v4 C& D*  7 k9 K, {! k* h& q  k9 f
ERROR at line 1:  
' {/ n5 u" b0 T2 i& yORA-01467: sort key too long  
- h, @* M1 N3 l% v% g+ _7 m5 U! h% u3 F" f' q9 m: \
SQL> SHOW PARAMETER DB_BLOCK_SIZE  
) X' U! D# E5 G" INAME TYPE VALUE  
# e' @7 D/ l  c3 q' `) O' d) |------------------------------------ ----------- ------------------------------  
- {$ [2 T9 K- B8 x: Bdb_block_size integer 16384  % l9 {- f! y- t0 c: F, J/ g
而这个问题在10g已经得到了解决,测试发现即使有30多个F_LINK的调用,也没有出现ORA-1467错误。  ) i9 U" W8 j& ^3 `" o( ]7 m. T
SQL> CONN YANGTK/YANGTK@YTK已连接。  
) e0 ?! v" \  P7 m4 YSQL> SELECT * FROM V$VERSION;  6 ?6 V% k7 \: p1 D7 j0 S: v/ [
BANNER  
1 Z& F, e* f) ^+ x7 J----------------------------------------------------------------  
- z' M; r7 t+ j; `Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod  
0 `' V+ J$ j5 kPL/SQL Release 10.2.0.1.0 - Production  5 X* v, @" F; O0 P' `( l4 [
CORE 10.2.0.1.0 Production  1 C1 k* w9 C( j. L% i
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production  6 ]5 x( P, }- r$ t' z
NLSRTL Version 10.2.0.1.0 - Production  
7 i- R3 B$ l) z7 p9 R2 g( f4 BSQL> COL F_LINK(1) FORMAT A20  7 U# I7 _' D6 n/ `6 Z' l0 P
SQL> COL F_LINK(2) FORMAT A20  
" G$ a* c; [5 Q1 HSQL> COL F_LINK(3) FORMAT A20  
( s3 e: x- W  B# A+ \2 s* YSQL> COL F_LINK(4) FORMAT A20  
0 B8 t4 D4 {! L* aSQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3), F_LINK(4)  8 i) [4 ]; n/ |0 D5 w, y' x" N
2 FROM T  
+ q. _- @9 a! T1 A3 WHERE ROWNUM < 5  
' h# e& W' S  u! @4 GROUP BY OWNER;  
: S3 p/ ?% p+ g* X$ I! @: {OWNER F_LINK(1) F_LINK(2) F_LINK(3) F_LINK(4)  , {6 q+ T) Z- H3 V* r  m# W
-------------------- -------------------- -------------------- -------------------- ------  
2 f7 w) a3 ]: `$ X" nSYS 1,1,1,1 2,2,2,2 3,3,3,3 4,4,4,4  - w/ G5 H5 i, H2 c) i
在9i上如果碰到这个问题,可以考虑使用变通的方法解决。比如使用CONNECT BY语句来代替自定义聚集函数。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-8 01:48 , Processed in 0.270464 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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