2

Java から Oracle 9i データベースに対して次のようなクエリを実行したいと考えています (テーブル構造の例とデータの例を以下に示します)。

部門番号を選択
, SUBSTR(コンマリスト, 2) コンマリスト
FROM (部門番号を選択
        , SYS_CONNECT_BY_PATH(ename, ',') コンマリスト
        、row_number
        、row_count
        FROM (部門番号を選択
               、エネーム
               , ROW_NUMBER()OVER(PARTITION BY deptno
                                       ORDER BY empno) 行番号
               , COUNT(*)OVER(PARTITION BY deptno) row_count
               FROM wd_emp)
        行番号 = 1 で開始
        CONNECT BY deptno = 前の deptno
        AND 行番号 = 前の行番号 + 1)
WHERE 行番号 = 行数;

これはうまくいきます。ただし、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)
                   ,MGR NUMBER(4)
                   ,HIREDATE DATE
                   ,販売番号(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,'チーム 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', 'チーム リード', 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', 'チーム リード', 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', 'チーム リード', 28, to_date('04-JAN-2000', 'DD-MON-RRRR'), 800, 50);
INSERT INTO WD_EMP VALUES(26,'McGINTY', 'チーム リード', 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);
4

3 に答える 3

2

SQLでコンマリストを作成する必要がありますか?

とにかくこれをJavaから実行しているので、「parent_id」、「child_id」、「tree_level」列の行をクエリして、アプリケーションコードに従業員パスを作成できますか?とにかく今はリストに分割していると思います(4000文字の文字列を直接表示することはできません)。

于 2009-05-01T10:18:14.353 に答える
0

2 つのアイデア:

  • 実際の文字列を連結するのではなく、より短いプレースホルダーを連結し、実際の名前を挿入するために (Java またはその他の方法で) いくつかの置換メソッドを使用します

  • 複数の列を作成できます。comma_list_ では、それぞれが 400 人の従業員の n 番目のグループを保持します。最終的な値は、クライアントでこれらの列を連結した結果になります。

于 2009-06-05T16:35:56.337 に答える
0

varchar2 の 4000 文字の制限は列のみであることを理解していました。たとえば、PL/SQL では、varchar2 の長さが実際にははるかに大きくなることが許可されていました。クエリが間違って再帰し、大きなデカルト積を生成していないことを確信していますか?

于 2009-08-13T19:26:21.680 に答える