本文发表在 rolia.net 枫下论坛CREATE TABLE test(A NUMBER, B NUMBER, C NUMBER);
INSERT INTO test VALUES (2,1,2);
INSERT INTO test VALUES (2,4,5);
INSERT INTO test VALUES (4,3,8);
INSERT INTO test VALUES (4,2,6);
INSERT INTO test VALUES (7,1,1);
INSERT INTO test VALUES (7,2,2);
INSERT INTO test VALUES (7,3,3);
INSERT INTO test VALUES (7,4,4);
COMMIT;
CREATE OR REPLACE TYPE t_row AS OBJECT (
r_num NUMBER
,text VARCHAR2(2000)
)
/
CREATE OR REPLACE TYPE t_matrix AS TABLE OF t_row
/
CREATE OR REPLACE FUNCTION f_matrix RETURN t_matrix
AS
lv_data t_matrix := t_matrix();
lv_text VARCHAR2(2000);
lv_lastrow NUMBER;
lv_lastcol NUMBER;
BEGIN
lv_lastrow := 0;
lv_lastcol := 1;
lv_text := NULL;
FOR lv_rec IN (SELECT * FROM test ORDER BY a,b)
LOOP
IF lv_lastrow <> lv_rec.a THEN
FOR i IN GREATEST(1,lv_lastrow) .. lv_rec.a - 1
LOOP
lv_data.EXTEND;
lv_data(i) := t_row(i,NULL);
END LOOP;
IF lv_lastrow>0 THEN
lv_data(lv_lastrow).text := lv_text;
END IF;
lv_lastrow := lv_rec.a;
lv_text := NULL;
lv_lastcol := 1;
END IF;
lv_text := lv_text||SUBSTR(RPAD('*',lv_rec.b - lv_lastcol+1,CHR(9)),2)||lv_rec.c;
lv_lastcol := lv_rec.b;
END LOOP;
IF lv_lastrow>0 THEN
lv_data.EXTEND;
lv_data(lv_lastrow) := t_row(lv_lastrow,lv_text);
END IF;
RETURN lv_data;
END f_matrix;
/
最后,到TOAD里面执行这么一个查询:
SELECT text FROM TABLE(CAST(f_matrix AS t_matrix)) order by r_num;
结果集是一个包含了TAB分隔符的字串。选择 SAVE AS -> DELIMITED TEXT 到 CLIPBOARD, 然后到一个空白的 EXCEL SHEET 里面粘贴。更多精彩文章及讨论,请光临枫下论坛 rolia.net
INSERT INTO test VALUES (2,1,2);
INSERT INTO test VALUES (2,4,5);
INSERT INTO test VALUES (4,3,8);
INSERT INTO test VALUES (4,2,6);
INSERT INTO test VALUES (7,1,1);
INSERT INTO test VALUES (7,2,2);
INSERT INTO test VALUES (7,3,3);
INSERT INTO test VALUES (7,4,4);
COMMIT;
CREATE OR REPLACE TYPE t_row AS OBJECT (
r_num NUMBER
,text VARCHAR2(2000)
)
/
CREATE OR REPLACE TYPE t_matrix AS TABLE OF t_row
/
CREATE OR REPLACE FUNCTION f_matrix RETURN t_matrix
AS
lv_data t_matrix := t_matrix();
lv_text VARCHAR2(2000);
lv_lastrow NUMBER;
lv_lastcol NUMBER;
BEGIN
lv_lastrow := 0;
lv_lastcol := 1;
lv_text := NULL;
FOR lv_rec IN (SELECT * FROM test ORDER BY a,b)
LOOP
IF lv_lastrow <> lv_rec.a THEN
FOR i IN GREATEST(1,lv_lastrow) .. lv_rec.a - 1
LOOP
lv_data.EXTEND;
lv_data(i) := t_row(i,NULL);
END LOOP;
IF lv_lastrow>0 THEN
lv_data(lv_lastrow).text := lv_text;
END IF;
lv_lastrow := lv_rec.a;
lv_text := NULL;
lv_lastcol := 1;
END IF;
lv_text := lv_text||SUBSTR(RPAD('*',lv_rec.b - lv_lastcol+1,CHR(9)),2)||lv_rec.c;
lv_lastcol := lv_rec.b;
END LOOP;
IF lv_lastrow>0 THEN
lv_data.EXTEND;
lv_data(lv_lastrow) := t_row(lv_lastrow,lv_text);
END IF;
RETURN lv_data;
END f_matrix;
/
最后,到TOAD里面执行这么一个查询:
SELECT text FROM TABLE(CAST(f_matrix AS t_matrix)) order by r_num;
结果集是一个包含了TAB分隔符的字串。选择 SAVE AS -> DELIMITED TEXT 到 CLIPBOARD, 然后到一个空白的 EXCEL SHEET 里面粘贴。更多精彩文章及讨论,请光临枫下论坛 rolia.net