【问题标题】:Oracle SYS_CONNECT_BY_PATH hitting 4000 character limitOracle SYS_CONNECT_BY_PATH 达到 4000 个字符的限制
【发布时间】:2010-10-23 02:09:18
【问题描述】:

我想通过 Java 对 Oracle 9i 数据库运行如下查询(下面是示例表结构和示例数据)。

选择部门号 , SUBSTR(comma_list, 2) comma_list 从(选择部门号 , SYS_CONNECT_BY_PATH(ename, ',') comma_list , 行号 , 行数 从(选择部门号 , 姓名 , ROW_NUMBER()OVER(PARTITION BY deptno ORDER BY empno) row_number , COUNT(*)OVER(PARTITION BY deptno) row_count 来自 wd_emp) 从 row_number = 1 开始 通过 deptno 连接 = 先前的 deptno AND row_number = PRIOR row_number + 1) WHERE row_number = row_count;

这很好用。但是,如果构建 comma_list 的 sys_connect_by_path 达到 varchar2 4000 个字符的限制,则会收到 "ORA-01489: result of string concatenation is too long" 错误。

是否有人对如何克服此限制以使我的串联可以超过 4000 个字符有任何建议?

表格和示例数据:

CREATE TABLE WD_DEPT(DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY ,DNAME VARCHAR2(14) ,LOC VARCHAR2(13)); CREATE TABLE WD_EMP(EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY ,ENAME VARCHAR2(10) ,JOB VARCHAR2(10) ,经理编号(4) ,雇用日期 ,SAL 编号(7,2) ,DEPTNO NUMBER(2) 约束 FK_DEPTNO 参考 WD_DEPT); INSERT INTO WD_DEPT VALUES(10,'TEAM GREGORY','TABLE 3'); 插入 WD_DEPT 值(20,'TEAM HANLEY','表 2'); INSERT INTO WD_DEPT VALUES(30,'TEAM OFFIAH','TABLE 4'); INSERT INTO WD_DEPT VALUES(40,'TEAM BOTICA','TABLE 1'); INSERT INTO WD_DEPT VALUES(50,'TEAM SKERRETT','TABLE 4'); INSERT INTO WD_DEPT VALUES(60,'TEAM McGINTY','TABLE 1'); INSERT INTO WD_DEPT VALUES(70,'EMPTY TEAM','NO TABLE'); 插入 WD_EMP 值(11,'GREGORY','TEAM LEAD',28,to_date('18-JAN-2000','DD-MON-RRRR'),800,10); 插入 WD_EMP 值(12,'BELL', 'DEVELOPER', 11, to_date('17-JAN-2000', 'DD-MON-RRRR'), 600, 10); 插入 WD_EMP 值(13,'CLARKE', 'DEVELOPER', 11, to_date('16-JAN-2000', 'DD-MON-RRRR'), 600, 10); 插入 WD_EMP 值(14,'HANLEY','团队领导',28,to_date('15-JAN-2000','DD-MON-RRRR'),800,20); 插入 WD_EMP 值(15,'BETTS', 'CONTRACTOR', 14, to_date('14-JAN-2000', 'DD-MON-RRRR'), 700, 20); 插入 WD_EMP 值(16,'MILES', 'CONTRACTOR', 14, to_date('13-JAN-2000', 'DD-MON-RRRR'), 700, 20); 插入 WD_EMP 值(17,'HAMPSON','DEVELOPER',14,to_date('12-JAN-2000','DD-MON-RRRR'),600,20); 插入 WD_EMP 值(18,'PRESTON', 'DEVELOPER', 14, to_date('11-JAN-2000', 'DD-MON-RRRR'), 600, 20); 插入 WD_EMP 值(19,'OFFIAH','团队领导',28,to_date('10-JAN-2000','DD-MON-RRRR'),800,30); 插入 WD_EMP 值(20,'PLATT', 'DEVELOPER', 19, to_date('09-JAN-2000', 'DD-MON-RRRR'), 600, 30); 插入 WD_EMP 值(21,'POTTER','DEVELOPER',19,to_date('08-JAN-2000','DD-MON-RRRR'),600,30); 插入 WD_EMP 值(22,'CASE', 'DEVELOPER', 19, to_date('07-JAN-2000', 'DD-MON-RRRR'), 600, 30); 插入 WD_EMP 值(23,'BOTICA','团队领导',28,to_date('06-JAN-2000','DD-MON-RRRR'),800,40); 插入 WD_EMP 值(24,'GILL', 'DEVELOPER', 23, to_date('05-JAN-2000', 'DD-MON-RRRR'), 600, 40); 插入 WD_EMP 值(25,'SKERRETT','团队领导',28,to_date('04-JAN-2000','DD-MON-RRRR'),800,50); 插入 WD_EMP 值(26,'McGINTY','TEAM LEAD',28,to_date('03-JAN-2000','DD-MON-RRRR'),800,60); 插入 WD_EMP 值(27,'LOWE','MANAGER',28,to_date('02-JAN-2000','DD-MON-RRRR'),900,NULL); 插入 WD_EMP 值(28,'MONIE','MANAGER',NULL,to_date('01-JAN-2000','DD-MON-RRRR'),1000,NULL);

【问题讨论】:

    标签: java sql oracle analytics


    【解决方案1】:

    是否需要在 SQL 中构建逗号列表?

    既然您是从 Java 运行它,也许您可​​以查询具有“parent_id”、“child_id”、“tree_level”列的行并在应用程序代码中构建员工路径?我想您现在无论如何都要将其拆分为一个列表(4000 个字符的字符串不能用于直接显示目的)。

    【讨论】:

    • 我需要将所有内容连接在一起,以便在基于文件的界面上发送。就像你说的,我可以改为拉多行,遍历 Java 中的行并连接。但我想知道我是否可以一击 DB 完成所有操作。
    • 我认为这在性能方面没有意义。您还将通过网络发送比所需更多的数据。但这是一个有趣的练习。谷歌“STRAGG”或“sys_connect_by_path”有几种解决问题的方法。我相信它可以与 CLOB 一起使用。
    【解决方案2】:

    两个想法:

    • 不要连接实际的字符串,而是使用较短的占位符并使用一些替换方法(在 java 中或其他方式中)插入真实姓名

    • 您可以创建多个列:comma_list_,其中每个列包含第 n 组 400 名员工。最终值将通过在客户端中连接这些列而产生。

    【讨论】:

      【解决方案3】:

      我了解到 varchar2 的 4000 个字符限制仅适用于列——实际上允许 varchar2 的长度更大,例如在 PL/SQL 中。您确定您的查询没有错误地递归并生成一些大型笛卡尔积吗?

      【讨论】:

        猜你喜欢
        • 2012-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-02
        • 2019-05-08
        • 1970-01-01
        • 2018-08-21
        • 2016-05-29
        相关资源
        最近更新 更多