2

我想对来自 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:字符串连接的结果太长”错误。

是否有人对如何克服此限制有任何建议,以便我的串联可以超过 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);
4

3 回答 3

2

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

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

于 2009-05-01T10:18:14.353 回答
0

两个想法:

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

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

于 2009-06-05T16:35:56.337 回答
0

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

于 2009-08-13T19:26:21.680 回答