在使用自定义聚集函数时出现了一个ORA-1467错误。

根据Oracle文档上的描述,1467错误是由于排序的键值超过了DB_BLOCK_SIZE。

但是出现错误的SQL似乎并不满足这个条件。下面简单构造这个错误:

SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (
2 STR VARCHAR2(30000),
3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER,
4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,
5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER,
6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER
7 )
8 /

Type created.

SQL> CREATE OR REPLACE TYPE BODY T_LINK IS
2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER IS
3 BEGIN
4 SCTX := T_LINK(NULL);
5 RETURN ODCICONST.SUCCESS;
6 END;
7
8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS
9 BEGIN
10 SELF.STR := SELF.STR || VALUE || ',';
11 RETURN ODCICONST.SUCCESS;
12 END;
13
14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBER) RETURN NUMBER IS
15 BEGIN
16 RETURNVALUE := SUBSTR(SELF.STR, 1, LENGTH(SELF.STR) - 1);
17 RETURN ODCICONST.SUCCESS;
18 END;
19
20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS
21 BEGIN
22 NULL;
23 RETURN ODCICONST.SUCCESS;
24 END;
25 END;
26 /

Type body created.

SQL> CREATE OR REPLACE FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2
2 AGGREGATE USING T_LINK;
3 /

Function created.

首先是构造自定义聚集函数,关于这个函数的详细说明,可以参考:http://yangtingkun.itpub.net/post/468/3380

SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS;

Table created.

SQL> SELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)
2 FROM T
3 GROUP BY OWNER;
SELECT OWNER, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)
*
ERROR at line 1:
ORA-01467: sort key too long

SQL> DESC T
Name Null? Type
--------------------------------- -------- --------------
OWNER VARCHAR2(30)
OBJECT_NAME VARCHAR2(128)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(18)
CREATED DATE
LAST_DDL_TIME DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)

OWNER列的长度只有30,而且即使换成长度为1的列也没有作用。

SQL> SELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)
2 FROM T
3 GROUP BY TEMPORARY;
SELECT TEMPORARY, F_LINK(OBJECT_NAME), F_LINK(SUBOBJECT_NAME), F_LINK(OBJECT_ID)
*
ERROR at line 1:
ORA-01467: sort key too long

既然和GROUP BY列没有太大的关系,那么是否与F_LINK输入列的长度有关:

SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
2 FROM T
3 GROUP BY OWNER;
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
*
ERROR at line 1:
ORA-01467: sort key too long

即使将F_LINK的输入参数变成常数1、2、3,问题仍然会出现,看来和F_LINK输入参数的长度也没有关系。

虽然与F_LINK输入参数长度没有关系,但是和F_LINK函数调用次数有关,将F_LINK三次调用变为两次调用,就可以得到结果:

SQL> SELECT OWNER, F_LINK(1), F_LINK(2)
2 FROM T
3 WHERE ROWNUM < 10
4 GROUP BY OWNER;

OWNER F_LINK(1) F_LINK(2)
------------------------------ ------------------------------ -----------------
SYS 1,1,1,1,1,1,1,1,1 2,2,2,2,2,2,2,2,2

这个问题在9i上就会出现,而且与DB_BLOCK_SIZE的大小没有关系。在DB_BLOCK_SIZE为8K和16K的环境下测试,得到的结果完全一样。

SQL> CREATE TABLE T AS SELECT * FROM ALL_OBJECTS;

Table created.

SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
2 FROM T
3 GROUP BY OWNER;
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
*
ERROR at line 1:
ORA-01467: sort key too long

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_NUMBER NUMBER;
3 V_STR VARCHAR2(4000);
4 V_RES NUMBER;
5 BEGIN
6 V_RES := DBMS_UTILITY.GET_PARAMETER_VALUE('db_block_size', V_NUMBER, V_STR);
7 DBMS_OUTPUT.PUT_LINE(V_NUMBER);
8 END;
9 /
8192

PL/SQL procedure successfully completed.

SQL> CONN TEST@GPODB
Enter password:
Connected.
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
2 FROM T
3 GROUP BY OWNER;
SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3)
*
ERROR at line 1:
ORA-01467: sort key too long

SQL> SHOW PARAMETER DB_BLOCK_SIZE

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 16384

而这个问题在10g已经得到了解决,测试发现即使有30多个F_LINK的调用,也没有出现ORA-1467错误。

SQL> CONN YANGTK/YANGTK@YTK已连接。
SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

SQL> COL F_LINK(1) FORMAT A20
SQL> COL F_LINK(2) FORMAT A20
SQL> COL F_LINK(3) FORMAT A20
SQL> COL F_LINK(4) FORMAT A20
SQL> SELECT OWNER, F_LINK(1), F_LINK(2), F_LINK(3), F_LINK(4)
2 FROM T
3 WHERE ROWNUM < 5
4 GROUP BY OWNER;

OWNER F_LINK(1) F_LINK(2) F_LINK(3) F_LINK(4)
-------------------- -------------------- -------------------- -------------------- ------
SYS 1,1,1,1 2,2,2,2 3,3,3,3 4,4,4,4

在9i上如果碰到这个问题,可以考虑使用变通的方法解决。比如使用CONNECT BY语句来代替自定义聚集函数。

SQL> SELECT OWNER, MAX(LTRIM(SYS_CONNECT_BY_PATH(OBJECT_NAME, ','), ',')) OBJECT_NAME,
2 MAX(LTRIM(SYS_CONNECT_BY_PATH(SUBOBJECT_NAME, ','), ',')) SUBOBJECT_NAME,
3 MAX(LTRIM(SYS_CONNECT_BY_PATH(OBJECT_ID, ','), ',')) OBJECT_ID
4 FROM
5 (
6 SELECT OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID,
7 ROW_NUMBER() OVER(PARTITION BY OWNER ORDER BY OBJECT_NAME) RN
8 FROM T
9 WHERE OBJECT_ID BETWEEN 30014 AND 30017
10 )
11 START WITH RN = 1
12 CONNECT BY PRIOR RN + 1 = RN
13 AND PRIOR OWNER = OWNER
14 GROUP BY OWNER;

OWNER OBJECT_NAME SUBOBJECT_NAM OBJECT_ID
-------- ---------------------------------------------------- ------------- ---------------
OLAPSYS ALL$OLAP1_CUBES,ALL$OLAPMR_DIM_LEVELS_KEYMAPS 30016,30017
PUBLIC CWM2_OLAP_AW_ACCESS,CWM2_OLAP_INSTALLER 30014,30015

如果无法聚集函数函数无法代替,可以使用下面的办法:

SQL> SELECT A.OWNER, A.OBJECT_NAME, A.SUBOBJECT_NAME, B.OBJECT_ID
2 FROM
3 (
4 SELECT OWNER, F_LINK(OBJECT_NAME) OBJECT_NAME,
5 F_LINK(SUBOBJECT_NAME) SUBOBJECT_NAME
6 FROM T
7 WHERE OBJECT_ID BETWEEN 30014 AND 30017
8 GROUP BY OWNER
9 ) A,
10 (
11 SELECT OWNER, F_LINK(OBJECT_ID) OBJECT_ID
12 FROM T
13 WHERE OBJECT_ID BETWEEN 30014 AND 30017
14 GROUP BY OWNER
15 ) B
16 WHERE A.OWNER = B.OWNER;

OWNER OBJECT_NAME SUBOBJECT_NAM OBJECT_ID
-------- ---------------------------------------------------- ------------- ---------------
OLAPSYS ALL$OLAP1_CUBES,ALL$OLAPMR_DIM_LEVELS_KEYMAPS 30016,30017
PUBLIC CWM2_OLAP_AW_ACCESS,CWM2_OLAP_INSTALLER 30014,30015

只要避免在同一个子查询中自定义聚集函数不要超过限定数量就可以了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-69400/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-69400/

Oracle9i的1467错误相关推荐

  1. proftpd ldap mysql_安装proftpd+ldap报错

    安装proftpd+ldap报错 (2012-11-09 11:36:29) 标签: it 杂谈 mod_ldap.c:68:18: 错误:lber.h:没有那个文件或目录 mod_ldap.c:69 ...

  2. 安装Oracle9I出现加载数据库时出错:areasQueries错误,提示停止该组件或所有组件安装,之后安装不能进行...

    今天项目组同事遇到这个问题,解决办法如下: 看了一下oracle安装的文件记录,发现问题所在,原来我的oracle安装目带有汉字 d:\oracle安装\oracle9i\disk1 问题就在这个&q ...

  3. MyEclipse连接oracle9i:invalid or unknown NLS parameter value specified错误

    解决方法: 在本机控制面板中修改区域和语言选项,把"区域选项"中的"标准和格式"自定义为"英语(美国)"; 重启MyEclipse,查看he ...

  4. 诊断ORA-08103错误

    ORA-08103问题的诊断最好是能生成8103错误的ERROR STACK TRACE, 在TRACE中会记录具体引发8103的对象的OBJ和OBJD,这便于我们定位可能存在corruption的对 ...

  5. [转]EXP-00056: 遇到 ORACLE 错误 31600

    exp system/password full=y file=e:\20030904.dmp log=e:\20030904.log     连接到: Oracle9i Enterprise Edi ...

  6. asp oracle9i 链接oracle,解决使用ASP无法连接ORACLE 9i数据库的问题

    今天,在一台WIN2K SERVER 服务器上,通过ASP安装在本机的 Oracle9i 时,发现错误,根本无法连接上数据库.其错误描述如下: Microsoft OLE DB Provider fo ...

  7. 配置Apache 2.2+PHP 5.2.9支持OCI通过Oracle9i Client连接Oracle

    有一个问题,公司电脑上装的是Oracle9i客户端,然后使用Apache 2.2+php 5连接oracle数据库,不管如何配置都不能使用OCI (使用oracle 10g的客户端只要去掉php.in ...

  8. erwin连接oracle数据库,erwin连接oracle9i数据库

    评论 # re: erwin连接oracle9i数据库 2008-05-14 17:25 为鹏飞 帮帮我好吗,我用的是oracle10g,也出现了这样的情况,现在还没解决.把您的联系方式发到我邮箱里我 ...

  9. 10g TNS 13541 监听错误 tnsping可以但是conn system/manager@mult1.net 报错

    oracle 10g : ORA-12514: TNS:listener does not currently know of service requested in connect descrip ...

  10. oracle撤销管理的方法,Oracle9i中利用自动撤销管理的优点

    在9i中,对回滚段进行了重新命名,现在将其作为撤销日志.在传统的操作上,回滚段保存的撤销信息,直到系统发送一个响应或者回滚语句. 人工撤销管理在Oracle9i仍然被使用,但绝大多数的Oracle D ...

最新文章

  1. SharePoint 2016 必备组件离线安装介绍
  2. 从ReLU到Sinc,26种神经网络激活函数可视化
  3. python实现网页登录时的rsa加密流程
  4. Codeforces Round #359 (Div. 2) D. Kay and Snowflake
  5. Linux中自动删除n天前日志
  6. Extension field添加到CDS view上的技术实现
  7. Linux文件IO-例会笔记总结
  8. Hive近百个常规函数详解
  9. 如何让政府性论坛外链最大利益化
  10. 样本修改 sample_如何在R中使用sample()获取样本?
  11. eclipse查看源码
  12. 如何解决win10语言栏消失变成空白问题
  13. CocosCreator接入穿山甲广告2-插屏广告
  14. localStorage的黑科技-js和css缓存机制
  15. C++ Primer Plus 第六版第二章编程练习答案
  16. 基于切比雪夫逼近法的滤波器的matlab设计与实现
  17. 洛谷P3647 [APIO2014] 连珠线 题解
  18. 生物学哲学:科学哲学的新视野
  19. AB测试-A/B Test
  20. rsync网络文件传输

热门文章

  1. 《千与千寻》告诉产品经理什么?
  2. Android黑白照片上色APP,黑白图片上色工具
  3. 【CI/CD】详解自动化开发之CI/CD(持续集成、持续交付、持续部署)
  4. MIP启发式算法:local branching
  5. 智能推荐系统开发中的十个关键注意点
  6. pointer在html作用,html-CSS中的“ cursor:pointer”效果为什么不起作用
  7. 《Android开源库》 Google 最新Hover Menu(悬浮菜单)
  8. 算法:合唱队形(最大上升子序列,线性DP)
  9. 宏定义是什么?为什么要进行宏定义?宏定义的格式
  10. 大数据入门最全组件思维导图