PostgreSQL Oracle 兼容性之 - DBMS_OUTPUT.PUT_LINE

本文对比了PostgreSQL与Oracle数据库中的调试技术,详细介绍了如何使用DBMS_OUTPUT.PUT_LINE和raise notice来输出过程变量,进行函数和存储过程的调试。通过具体示例,展示了两种数据库环境下调试信息的获取方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标签

PostgreSQL , Oracle , DBMS_OUTPUT.PUT_LINE , raise , notice


背景

在函数、存储过程中需要进行一些debug,输出一些过程变量的值时,PG中使用raise notice可以非常方便的得到。

Oracle

put_line在存储过程、函数中通常被用于调试,输出一些变量,时间值。

CREATE FUNCTION dept_salary (dnum NUMBER) RETURN NUMBER IS  
   CURSOR emp_cursor IS  
      SELECT sal, comm FROM emp WHERE deptno = dnum;  
   total_wages    NUMBER(11, 2) := 0;  
   counter        NUMBER(10) := 1;  
BEGIN  
  
   FOR emp_record IN emp_cursor LOOP  
      emp_record.comm := NVL(emp_record.comm, 0);  
      total_wages := total_wages + emp_record.sal  
         + emp_record.comm;  
      DBMS_OUTPUT.PUT_LINE('Loop number = ' || counter ||   
         '; Wages = '|| TO_CHAR(total_wages));  /* Debug line */  
      counter := counter + 1; /* Increment debug counter */  
   END LOOP;  
   /* Debug line */  
   DBMS_OUTPUT.PUT_LINE('Total wages = ' ||  
     TO_CHAR(total_wages));   
   RETURN total_wages;  
  
END dept_salary;  

Assume the EMP table contains the following rows:

EMPNO          SAL     COMM     DEPT  
-----        ------- -------- -------  
1002           1500      500      20  
1203           1000               30  
1289           1000               10  
1347           1000      250      20  

Assume the user executes the following statements in SQL*Plus:

SET SERVEROUTPUT ON  
VARIABLE salary NUMBER;  
EXECUTE :salary := dept_salary(20);  

The user would then see the following information displayed in the output pane:

Loop number = 1; Wages = 2000  
Loop number = 2; Wages = 3250  
Total wages = 3250  
  
PL/SQL procedure successfully executed.  

PostgreSQL

PostgreSQL plpgsql存储过程,其他存储过程语言同样有类似的用法(plr, plpython, plperl, pltcl, pljava, pllua等)

以plpgsql为例,使用raise notice即可用于输出调试信息,例如

postgres=# do language plpgsql $$  
declare  
begin  
  raise notice 'now: %, next time: %', now(), now()+interval '1 day';  
end;  
$$;  
  
输出  
  
NOTICE:  now: 2018-08-18 16:15:30.209386+08, next time: 2018-08-19 16:15:30.209386+08  
DO  
Time: 0.335 ms  

捕获状态变量信息

https://www.postgresql.org/docs/devel/static/plpgsql-statements.html

https://www.postgresql.org/docs/devel/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING

GET STACKED DIAGNOSTICS ....  
  
GET DIAGNOSTICS ...  

参考

https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_output.htm#BABEHIEG

https://www.postgresql.org/docs/11/static/plpgsql-errors-and-messages.html

CREATE OR REPLACE PROCEDURE dump_table_to_csv (p_tname IN VARCHAR2, p_dir IN VARCHAR2, p_filename IN VARCHAR2) IS l_output UTL_FILE.file_type; l_theCursor INTEGER DEFAULT DBMS_SQL.open_cursor; l_columnValue VARCHAR2 (4000); l_status INTEGER; l_query VARCHAR2 (1000) DEFAULT 'select * from ' || p_tname; l_colCnt NUMBER := 0; l_separator VARCHAR2 (1); l_descTbl DBMS_SQL.desc_tab; BEGIN l_output := UTL_FILE.fopen (p_dir, p_filename, 'w'); EXECUTE IMMEDIATE 'alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss'' '; DBMS_SQL.parse (l_theCursor, l_query, DBMS_SQL.native); DBMS_SQL.describe_columns (l_theCursor, l_colCnt, l_descTbl); FOR i IN 1 .. l_colCnt LOOP DBMS_SQL.define_column (l_theCursor, i, l_columnValue, 4000); END LOOP; l_status := DBMS_SQL.execute (l_theCursor); WHILE (DBMS_SQL.fetch_rows (l_theCursor) > 0) LOOP l_separator := ''; FOR i IN 1 .. l_colCnt LOOP DBMS_SQL.COLUMN_VALUE (l_theCursor, i, l_columnValue); UTL_FILE.put (l_output, l_separator || l_columnValue); l_separator := ','; END LOOP; UTL_FILE.new_line (l_output); END LOOP; DBMS_SQL.close_cursor (l_theCursor); UTL_FILE.fclose (l_output); EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; EXCEPTION WHEN OTHERS THEN EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; RAISE; END; 这个是oracle的存储过程,我想要把它给转成postgreSql的。其中我postgreSql数据库里所有的表名和字段都是小写的,但是我转成postgreSql的这个存储过程的名字我还是希望保留着大写的。还有就是你还要给出我这两种数据库的存储过程的运行方法以及查询结果方法,像 “ postgreSQL: CALL "SP_CREATE_RP_GRPSVRWORK_CNT"('2024-03-04'::timestamp, '2024-03-05'::timestamp); -- 或者指定具体日期范围 SELECT * FROM rp_grpsvrworkcnt WHERE offhktm BETWEEN '2024-03-04' AND '2024-03-05' ORDER BY offhktm DESC; oracle: BEGIN SP_CREATE_RP_GRPSVRWORK_CNT(TO_DATE('2024-03-04', 'YYYY-MM-DD'), TO_DATE('2024-03-05', 'YYYY-MM-DD')); END; SELECT * FROM RP_GRPSVRWORKCNT WHERE OFFHKTM BETWEEN TO_DATE('2024-03-04', 'YYYY-MM-DD') AND TO_DATE('2024-03-05', 'YYYY-MM-DD') ORDER BY OFFHKTM DESC; ”这样
03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值