Eigentlich hat doch schon ein jeder PL/SQL-Entwickler (und natürlich auch jede Entwicklerin ) sich über das Package dbms_output.put_line geärgert.
Denn:
- Der Package und Procedure-Name ist viel zu lang:-)
- Es kann nur sehr wenige Datentypen (Text, Date, Number) ausgeben
- Wenn man die Ausgabe nicht richtig einstellt, ist sie weg
- Die Ausgabe bekommt man erst, wenn die Routine zuende ist
- Wenn die Ausgabe über einen Job (z.B. dbms_scheduler) erfolgen soll, verschwindet sie im Nirvana.
Ok, schauen wir mal, welche Probleme wir lösen können:
CREATE OR REPLACE PROCEDURE P_TEST
IS PROCEDURE P(P_TEXT)
IS
BEGIN DBMS_OUTPUT.PUT_LINE(P_TEXT);
END;
BEGIN
P('Hallo');
P('Ist das nicht schön kurz für ein Oracle Package?');
END;
/
Oder als eigenständige Prozedur:
CREATE OR REPLACE PROCEDURE SCOTT.PROCEDURE
(TEXT IN VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(TEXT);
END;
/
BEGIN
P('Hallo Welt');
END;
/
Umleitung von DBMS_OUTPUT zu PIPE: Damit können Sie am Ende des Programms einen Aufruf platzieren, der den DBMS_OUTPUT Puffer ausliest und in eine Pipe schickt. In einer anderen Session kann dann die Ausgabe erfolgen.
CREATE OR REPLACE PROCEDURE TEST_AUSGABE
-- Rechte notwendig: grant execute on dbms_pipe to scott;
IS
PROCEDURE DOP2PIPE
( PIPE_NAME IN VARCHAR2 DEFAULT 'DBMS_OUTPUT_PIPE')
IS
LINES DBMS_OUTPUT.CHARARR;
NUM_LINES NUMBER:=1000000;
BEGIN
DBMS_OUTPUT.GET_LINES(LINES, NUM_LINES);
FOR I IN 1..NUM_LINES
LOOP DBMS_PIPE.PACK_MESSAGE (LINES(I));
END LOOP;
IF (DBMS_PIPE.SEND_MESSAGE (PIPE_NAME)) <> 0 THEN
RAISE_APPLICATION_ERROR(-20500,'Fehler beim Senden in Pipe '||PIPE_NAME||' aufgetreten !');
END IF;
END;
BEGIN
DBMS_OUTPUT.ENABLE(NULL);
FOR I IN 1 .. 10 LOOP
DBMS_OUTPUT.PUT_LINE('Zeile='||I);
END LOOP;
DOP2PIPE; -- <=######## Umwandelung von dbms_output in Pipe END;
/
CREATE OR REPLACE PROCEDURE GET_DOUT_FROM_PIPE
(PIPE_NAME IN VARCHAR2 DEFAULT 'DBMS_OUTPUT_PIPE')
IS
V_MESSAGE VARCHAR2(32767);
V_TIMEOUT NUMBER:=120;
BEGIN
IF (DBMS_PIPE.RECEIVE_MESSAGE(PIPE_NAME,V_TIMEOUT)) <> 0 THEN
RAISE_APPLICATION_ERROR(-20501,'Fehler beim Lesen aus Pipe '||PIPE_NAME||' aufgetreten !');
END IF;
LOOP
EXIT WHEN DBMS_PIPE.NEXT_ITEM_TYPE = 0;
DBMS_PIPE.UNPACK_MESSAGE(V_MESSAGE);
DBMS_OUTPUT.PUT_LINE(V_MESSAGE);
END LOOP;
END;
/
Umleitung von dbms_output zu htp
CREATE OR REPLACE PROCEDURE test_ausgabe
IS
PROCEDURE dop2htp IS
lines dbms_output.chararr;
num_lines number:=1000000;
BEGIN
dbms_output.get_lines(lines, num_lines);
FOR i IN 1..num_lines LOOP
htp.p(lines(i)||'<BR>');
END LOOP;
END;
BEGIN
dbms_output.enable(null);
FOR i IN 1 .. 10 LOOP
dbms_output.put_line('Zeile='||i);
END LOOP;
dop2htp; -- <=######## Umwandelung von dbms_output in htp.p Ausgabe
END;
/
DBMS_OUPUT in CLOB speichern
VARIABLE console_clob CLOB
DECLARE
v_clob CLOB;
v_cr VARCHAR2(16):=chr(10); -- Zeilenumbruchzeichen
PROCEDURE dbms_output2clob IS
lines dbms_output.chararr;
num_lines number:=1000000;
BEGIN
dbms_lob.createtemporary(
lob_loc =>v_clob,
cache =>FALSE,
dur =>DBMS_LOB.CALL);
dbms_output.get_lines(lines, num_lines);
FOR i IN 1..num_lines LOOP
dbms_lob.writeappend(v_clob,length(lines(i)||v_cr),lines(i)||v_cr);
END LOOP;
:console_clob:=v_clob;
END;
BEGIN
FOR i IN 1 .. 100 LOOP
dbms_output.put_line(i||' Zeit :'||systimestamp);
END LOOP;
dbms_output2clob;
END;
/
set long 20000000
print console_clob
Weitere Tipps & Tricks erhalten Sie z.B. im PL/SQL, PL/SQL II und PL/SQL Packages Kurs.