DBMS_OUTPUT包用于向消息緩沖區(qū)發(fā)送消息,或者從消息緩沖區(qū)獲取消息。
下表列出了DBMS_OUTPUT包允許使用的存儲(chǔ)過程和函數(shù)。
函數(shù)/存儲(chǔ)過程 | 返回類型 | 描述 |
---|---|---|
DISABLE | N/A | 禁止訪問緩沖區(qū)的消息。 |
ENABLE(buffer size) | N/A | 允許訪問緩沖區(qū)的消息。 |
GET_LINE(line OUT, status OUT) | N/A | 從緩沖區(qū)中檢索一行文本。 |
GET_LINES(lines OUT, numlines IN OUT) | N/A | 從緩沖區(qū)中檢索行數(shù)組。 |
NEW_LINE | N/A | 放置一個(gè)行結(jié)束符。 |
PUT(item) | N/A | 在緩沖區(qū)中放置部分行消息。 |
PUT_LINE(item) | N/A | 在緩沖區(qū)中放置行消息。 |
SERVEROUTPUT(stdout) | N/A | 使用PUT 、PUT_LINE 或NEW_LINE 將消息直接發(fā)送到標(biāo)準(zhǔn)輸出或消息緩沖區(qū)。
|
下表列出了DBMS_OUTPUT包允許使用的公共變量。
變量名稱 | 變量類型 | 變量值 | 變量說明 |
---|---|---|---|
chararr | TABLE | - | 用于存儲(chǔ)多行消息文本。 |
CHARARR
變量CHARARR用于存儲(chǔ)多行消息文本。語法如下:
TYPE chararr IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
DISABLE
存儲(chǔ)過程DISABLE
用于清空消息緩沖區(qū)。在執(zhí)行存儲(chǔ)過程DISABLE
時(shí),將不能再訪問任何在緩沖區(qū)中的消息。
您可以使用存儲(chǔ)過程
ENABLE
或SERVEROUTPUT(TRUE)
來重新發(fā)送和接收消息。語法如下:DISABLE
示例BEGIN
DBMS_OUTPUT.DISABLE;
END;
ENABLE
存儲(chǔ)過程
示例ENABLE
允許向消息緩沖區(qū)發(fā)送消息,或從消息緩沖區(qū)中接收消息。語法如下:ENABLE [ (buffer_size INTEGER) ]
參數(shù)參數(shù)名稱 | 參數(shù)說明 |
---|---|
buffer_size | 消息緩沖區(qū)的最大長(zhǎng)度。以字節(jié)為單位。如果指定的buffer_size小于2000,那么會(huì)自動(dòng)把它設(shè)為2000。 |
下面的匿名代碼塊使消息傳遞的功能生效。通過設(shè)置
SERVEROUTPUT(TRUE)
,可以強(qiáng)制把消息送到標(biāo)準(zhǔn)輸出中。BEGIN
DBMS_OUTPUT.ENABLE;
DBMS_OUTPUT.SERVEROUTPUT(TRUE);
DBMS_OUTPUT.PUT_LINE('Messages enabled');
END;
Messages enabled
您也可以只通過使用
SERVEROUTPUT(TRUE)
實(shí)現(xiàn)相同的效果。BEGIN
DBMS_OUTPUT.SERVEROUTPUT(TRUE);
DBMS_OUTPUT.PUT_LINE('Messages enabled');
END;
Messages enabled
下面的匿名代碼塊使消息傳遞的功能生效,通過設(shè)置
SERVEROUTPUT(FALSE)
,可以將消息送到消息緩沖區(qū)中。BEGIN
DBMS_OUTPUT.ENABLE;
DBMS_OUTPUT.SERVEROUTPUT(FALSE);
DBMS_OUTPUT.PUT_LINE('Message sent to buffer');
END;
GET_LINE
使用存儲(chǔ)過程
示例GET_LINE
,您可以從消息緩沖區(qū)中獲取一行由行結(jié)束符終止的文本。語法如下:GET_LINE(line OUT VARCHAR2, status OUT INTEGER)
參數(shù)參數(shù)名稱 | 參數(shù)說明 |
---|---|
line | 用于從消息緩沖區(qū)接收文本行的變量。 |
status | 如果從消息緩沖區(qū)返回一行文本,返回0。如果沒有文本返回,返回1。 |
下面的匿名代碼塊,將表
emp
中的記錄以逗號(hào)分隔,并將分隔后的記錄以字符串的形式寫到消息緩沖區(qū)中。EXEC DBMS_OUTPUT.SERVEROUTPUT(FALSE);
DECLARE
v_emprec VARCHAR2(120);
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
DBMS_OUTPUT.ENABLE;
FOR i IN emp_cur LOOP
v_emprec := i.empno || ',' || i.ename || ',' || i.job || ',' ||
NVL(LTRIM(TO_CHAR(i.mgr,'9999')),'') || ',' || i.hiredate ||
',' || i.sal || ',' ||
NVL(LTRIM(TO_CHAR(i.comm,'9990.99')),'') || ',' || i.deptno;
DBMS_OUTPUT.PUT_LINE(v_emprec);
END LOOP;
END;
下面的匿名代碼塊,先從消息緩沖區(qū)中讀取文本消息,再將前一個(gè)示例寫入的消息寫入到
messages
表中,然后顯示消息中的記錄。CREATE TABLE messages (
status INTEGER,
msg VARCHAR2(100)
);
DECLARE
v_line VARCHAR2(100);
v_status INTEGER := 0;
BEGIN
DBMS_OUTPUT.GET_LINE(v_line,v_status);
WHILE v_status = 0 LOOP
INSERT INTO messages VALUES(v_status, v_line);
DBMS_OUTPUT.GET_LINE(v_line,v_status);
END LOOP;
END;
使用SELECT
查詢messages
表信息。SELECT msg FROM messages;
顯示結(jié)果如下: msg
-----------------------------------------------------------------
7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
(14 rows)
GET_LINES
您可以使用存儲(chǔ)過程
示例GET_LINES
從消息緩沖區(qū)中獲取多行文本,再將這些文本放到一個(gè)集合中。語法如下:GET_LINES(lines OUT CHARARR, numlines IN OUT INTEGER)
參數(shù)參數(shù)名稱 | 參數(shù)說明 |
---|---|
lines | 從消息緩沖區(qū)中接收文本行的表。關(guān)于lines的描述,參見變量CHARARR 。 |
numlines IN | 從消息緩沖區(qū)中取出的文本行數(shù)。 |
numlines OUT | 從消息緩沖區(qū)中實(shí)際取出的文本行數(shù)量。如果numlines的輸出值小于輸入值,那么表示在消息緩沖區(qū)中,沒有文本了。 |
示例中,使用存儲(chǔ)過程
GET_LINES
將放在消息緩沖區(qū)中emp
的記錄存放到一個(gè)數(shù)組中。EXEC DBMS_OUTPUT.SERVEROUTPUT(FALSE);
DECLARE
v_emprec VARCHAR2(120);
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
DBMS_OUTPUT.ENABLE;
FOR i IN emp_cur LOOP
v_emprec := i.empno || ',' || i.ename || ',' || i.job || ',' ||
NVL(LTRIM(TO_CHAR(i.mgr,'9999')),'') || ',' || i.hiredate ||
',' || i.sal || ',' ||
NVL(LTRIM(TO_CHAR(i.comm,'9990.99')),'') || ',' || i.deptno;
DBMS_OUTPUT.PUT_LINE(v_emprec);
END LOOP;
END;
DECLARE
v_lines DBMS_OUTPUT.CHARARR;
v_numlines INTEGER := 14;
v_status INTEGER := 0;
BEGIN
DBMS_OUTPUT.GET_LINES(v_lines,v_numlines);
FOR i IN 1..v_numlines LOOP
INSERT INTO messages VALUES(v_numlines, v_lines(i));
END LOOP;
END;
使用SELECT
查詢messages
表信息。SELECT msg FROM messages;
顯示結(jié)果如下: msg
-----------------------------------------------------------------
7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
(14 rows)
NEW_LINE
存儲(chǔ)過程
NEW_LINE
在消息緩沖區(qū)中寫入一個(gè)行結(jié)束符。語法如下:NEW_LINE
PUT
存儲(chǔ)過程
示例PUT
將一個(gè)字符串寫到消息緩沖區(qū)中。您可以使用存儲(chǔ)過程NEW_LINE
增加一個(gè)行結(jié)束符。語法如下:PUT(item VARCHAR2)
參數(shù)參數(shù)名稱 | 參數(shù)說明 |
---|---|
item | 寫到消息緩沖區(qū)中文本。 |
下面的示例使用存儲(chǔ)過程
PUT
展示了從表emp
中查詢出的雇員信息列表,這些雇員信息是以逗號(hào)分隔方式展現(xiàn)的。DECLARE
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
FOR i IN emp_cur LOOP
DBMS_OUTPUT.PUT(i.empno);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.ename);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.job);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.mgr);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.hiredate);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.sal);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.comm);
DBMS_OUTPUT.PUT(',');
DBMS_OUTPUT.PUT(i.deptno);
DBMS_OUTPUT.NEW_LINE;
END LOOP;
END;
顯示結(jié)果如下:7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
PUT_LINE
存儲(chǔ)過程
示例PUT_LINE
向消息緩沖區(qū)寫入一行帶有行結(jié)束符的文本。 語法如下:PUT_LINE(item VARCHAR2)
參數(shù)參數(shù)名稱 | 參數(shù)說明 |
---|---|
item | 寫入消息緩沖區(qū)的文本。 |
下面的示例使用存儲(chǔ)過程PUT_LINE
展示了從emp
表中查出的雇員記錄,這些記錄是以逗號(hào)分隔列表的形式展現(xiàn)的。
DECLARE
v_emprec VARCHAR2(120);
CURSOR emp_cur IS SELECT * FROM emp ORDER BY empno;
BEGIN
FOR i IN emp_cur LOOP
v_emprec := i.empno || ',' || i.ename || ',' || i.job || ',' ||
NVL(LTRIM(TO_CHAR(i.mgr,'9999')),'') || ',' || i.hiredate ||
',' || i.sal || ',' ||
NVL(LTRIM(TO_CHAR(i.comm,'9990.99')),'') || ',' || i.deptno;
DBMS_OUTPUT.PUT_LINE(v_emprec);
END LOOP;
END;
顯示結(jié)果如下:7369,SMITH,CLERK,7902,17-DEC-80 00:00:00,800.00,,20
7499,ALLEN,SALESMAN,7698,20-FEB-81 00:00:00,1600.00,300.00,30
7521,WARD,SALESMAN,7698,22-FEB-81 00:00:00,1250.00,500.00,30
7566,JONES,MANAGER,7839,02-APR-81 00:00:00,2975.00,,20
7654,MARTIN,SALESMAN,7698,28-SEP-81 00:00:00,1250.00,1400.00,30
7698,BLAKE,MANAGER,7839,01-MAY-81 00:00:00,2850.00,,30
7782,CLARK,MANAGER,7839,09-JUN-81 00:00:00,2450.00,,10
7788,SCOTT,ANALYST,7566,19-APR-87 00:00:00,3000.00,,20
7839,KING,PRESIDENT,,17-NOV-81 00:00:00,5000.00,,10
7844,TURNER,SALESMAN,7698,08-SEP-81 00:00:00,1500.00,0.00,30
7876,ADAMS,CLERK,7788,23-MAY-87 00:00:00,1100.00,,20
7900,JAMES,CLERK,7698,03-DEC-81 00:00:00,950.00,,30
7902,FORD,ANALYST,7566,03-DEC-81 00:00:00,3000.00,,20
7934,MILLER,CLERK,7782,23-JAN-82 00:00:00,1300.00,,10
SERVEROUTPUT
存儲(chǔ)過程
SERVEROUTPUT
將消息發(fā)送到命令行的標(biāo)準(zhǔn)輸出或消息緩沖區(qū)。通過設(shè)置SERVEROUTPUT(TRUE)
,能夠在隱含狀態(tài)下執(zhí)行存儲(chǔ)過程ENABLE
。SERVEROUTPUT
語法如下:SERVEROUTPUT(stdout BOOLEAN)
SERVEROUTPUT
的默認(rèn)值取決于實(shí)際應(yīng)用場(chǎng)景。例如:
- 在Oracle的SQL*PLUS中默認(rèn)為
SERVEROUTPUT(FALSE)
。說明 在Oracle的SQL*PLUS中,這個(gè)默認(rèn)值是通過SQL*PLUS的SET
命令控制。 - 在PSQL中默認(rèn)為
SERVEROUTPUT(TRUE)
。
參數(shù)名稱 | 參數(shù)說明 |
---|---|
stdout | 指定PUT 、PUT_LINE 或NEW_LINE 發(fā)送消息的目的地。
|
下面的匿名代碼塊,將第一條信息發(fā)送到命令行的標(biāo)準(zhǔn)輸出,第二條信息發(fā)送到消息緩沖區(qū)。
BEGIN
DBMS_OUTPUT.SERVEROUTPUT(TRUE);
DBMS_OUTPUT.PUT_LINE('This message goes to the command line');
DBMS_OUTPUT.SERVEROUTPUT(FALSE);
DBMS_OUTPUT.PUT_LINE('This message goes to the message buffer');
END;
顯示結(jié)果如下:This message goes to the command line
如果在同一個(gè)會(huì)話中執(zhí)行下面的匿名代碼塊,那么就會(huì)將前面示例中存放在消息緩沖區(qū)的消息做為一條新的信息在命令行上顯示出來。BEGIN
DBMS_OUTPUT.SERVEROUTPUT(TRUE);
DBMS_OUTPUT.PUT_LINE('Flush messages from the buffer');
END;
顯示結(jié)果如下:This message goes to the message buffer
Flush messages from the buffer