Oracle SYS_CONNECT_BY_PATH, превышающий ограничение в 4000 символов - PullRequest
2 голосов
/ 01 мая 2009

Я бы хотел выполнить запрос, подобный приведенному ниже, к базе данных Oracle 9i из Java (пример структуры таблицы и пример данных приведены ниже).

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;

Это отлично работает. Однако, если sys_connect_by_path, который создает comma_list, достигает предела 4000 символов varchar2, тогда я получаю "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)
                   ,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);

Ответы [ 3 ]

2 голосов
/ 01 мая 2009

Нужно ли строить список запятых в SQL?

Так как вы все равно запускаете это из Java, возможно, вы могли бы запросить строки со столбцами «parent_id», «child_id», «tree_level» и построить путь сотрудника в своем коде приложения? Я полагаю, что вы все равно теперь разбиваете его на список (строка из 4000 символов не может использоваться для прямого отображения).

0 голосов
/ 13 августа 2009

Я понял, что ограничение в 4000 символов для varchar2 было только для столбцов - что длинам varchar2 было разрешено увеличиваться НАМНОГО больше, например, в PL / SQL. Вы уверены, что ваш запрос не повторяется неправильно и генерирует какой-то большой декартовой продукт?

0 голосов
/ 05 июня 2009

Две идеи:

  • не объединяет фактические строки, но укорачивает местозаполнители и использует некоторый метод замены (в Java или иным способом) для вставки реальных имен

  • Вы можете создать несколько столбцов: comma_list_, где каждый содержит n-ю группу из 400 сотрудников. Окончательное значение будет результатом объединения этих столбцов в клиенте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...