Pregunta

Me gustaría ejecutar una consulta como la que se muestra a continuación en una base de datos Oracle 9i desde Java (a continuación se muestra una estructura de tabla de ejemplo y los datos de ejemplo).

SELECT deptno
,      SUBSTR(comma_list, 2)    comma_list
FROM   (SELECT deptno
        ,      SYS_CONNECT_BY_PATH(ename, ',')    comma_list
        ,      row_number
        ,      row_count
        FROM  (SELECT deptno
               ,      ename
               ,      ROW_NUMBER()OVER(PARTITION BY deptno
                                       ORDER BY     empno)    row_number
               ,      COUNT(*)OVER(PARTITION BY deptno)       row_count
               FROM   wd_emp)
        START WITH row_number = 1
        CONNECT BY deptno = PRIOR deptno
        AND        row_number = PRIOR row_number + 1)
WHERE  row_number = row_count;

Esto funciona bien. Sin embargo, si el sys_connect_by_path que construye comma_list alcanza el límite de caracteres varchar2 4000, entonces obtengo un " ORA-01489: el resultado de la concatenación de cadenas es demasiado largo " error.

¿Alguien tiene alguna sugerencia sobre cómo superar este límite para que mi concatenación pueda exceder los 4000 caracteres?

Tablas y datos de ejemplo:

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)
                   ,MGR NUMBER(4)
                   ,HIREDATE DATE
                   ,SAL NUMBER(7,2)
                   ,DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES WD_DEPT);

INSERT INTO WD_DEPT VALUES(10,'TEAM GREGORY','TABLE 3');
INSERT INTO WD_DEPT VALUES(20,'TEAM HANLEY','TABLE 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');

INSERT INTO WD_EMP VALUES(11,'GREGORY',  'TEAM LEAD',  28,   to_date('18-JAN-2000', 'DD-MON-RRRR'), 800,  10);
INSERT INTO WD_EMP VALUES(12,'BELL',     'DEVELOPER',  11,   to_date('17-JAN-2000', 'DD-MON-RRRR'), 600,  10);
INSERT INTO WD_EMP VALUES(13,'CLARKE',   'DEVELOPER',  11,   to_date('16-JAN-2000', 'DD-MON-RRRR'), 600,  10);
INSERT INTO WD_EMP VALUES(14,'HANLEY',   'TEAM LEAD',  28,   to_date('15-JAN-2000', 'DD-MON-RRRR'), 800,  20);
INSERT INTO WD_EMP VALUES(15,'BETTS',    'CONTRACTOR', 14,   to_date('14-JAN-2000', 'DD-MON-RRRR'), 700,  20);
INSERT INTO WD_EMP VALUES(16,'MILES',    'CONTRACTOR', 14,   to_date('13-JAN-2000', 'DD-MON-RRRR'), 700,  20);
INSERT INTO WD_EMP VALUES(17,'HAMPSON',  'DEVELOPER',  14,   to_date('12-JAN-2000', 'DD-MON-RRRR'), 600,  20);
INSERT INTO WD_EMP VALUES(18,'PRESTON',  'DEVELOPER',  14,   to_date('11-JAN-2000', 'DD-MON-RRRR'), 600,  20);
INSERT INTO WD_EMP VALUES(19,'OFFIAH',   'TEAM LEAD',  28,   to_date('10-JAN-2000', 'DD-MON-RRRR'), 800,  30);
INSERT INTO WD_EMP VALUES(20,'PLATT',    'DEVELOPER',  19,   to_date('09-JAN-2000', 'DD-MON-RRRR'), 600,  30);
INSERT INTO WD_EMP VALUES(21,'POTTER',   'DEVELOPER',  19,   to_date('08-JAN-2000', 'DD-MON-RRRR'), 600,  30);
INSERT INTO WD_EMP VALUES(22,'CASE',     'DEVELOPER',  19,   to_date('07-JAN-2000', 'DD-MON-RRRR'), 600,  30);
INSERT INTO WD_EMP VALUES(23,'BOTICA',   'TEAM LEAD',  28,   to_date('06-JAN-2000', 'DD-MON-RRRR'), 800,  40);
INSERT INTO WD_EMP VALUES(24,'GILL',     'DEVELOPER',  23,   to_date('05-JAN-2000', 'DD-MON-RRRR'), 600,  40);
INSERT INTO WD_EMP VALUES(25,'SKERRETT', 'TEAM LEAD',  28,   to_date('04-JAN-2000', 'DD-MON-RRRR'), 800,  50);
INSERT INTO WD_EMP VALUES(26,'McGINTY',  'TEAM LEAD',  28,   to_date('03-JAN-2000', 'DD-MON-RRRR'), 800,  60);
INSERT INTO WD_EMP VALUES(27,'LOWE',     'MANAGER',    28,   to_date('02-JAN-2000', 'DD-MON-RRRR'), 900,  NULL);
INSERT INTO WD_EMP VALUES(28,'MONIE',    'MANAGER',    NULL, to_date('01-JAN-2000', 'DD-MON-RRRR'), 1000, NULL);
¿Fue útil?

Solución

¿Es necesario construir la lista de comas en SQL?

Como está ejecutando esto desde Java de todos modos, tal vez podría consultar filas con '' parent_id '' , " child_id " ;, " tree_level " columnas y construir la ruta del empleado en su código de aplicación? Supongo que ahora lo estás dividiendo en una Lista (una cadena de 4000 caracteres no puede ser para fines de visualización directa).

Otros consejos

Dos ideas:

  • no concatene las cadenas reales, sino marcadores de posición más cortos y use algún método de reemplazo (en java o de otro modo) para insertar los nombres reales

  • podría crear múltiples columnas: comma_list_ donde cada una contiene el enésimo grupo de 400 empleados. El valor final resultaría de concatinar estas columnas en el cliente.

Estaba entendiendo que el límite de 4000 caracteres para varchar2 era solo para columnas, que las longitudes de varchar2 en realidad se permitían MUCHO más grandes, por ejemplo en PL / SQL. ¿Está seguro de que su consulta no es recurrente y genera un producto cartesiano grande?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top