移植Oracle procedure 到 postgresql

1.登录postgresql

psql -h 192.168.137.131 -p 5432 postgres sa
tusc@6789#JKL

2.创建用户

CREATE USER name thunisoft createdb; --(equal CREATE ROLE name LOGIN createdb);

3.创建数据库
create database test_database owner = thunisoft;

4.查看帮助 psql 下敲help

[thunisoft@localhost ~]$ psql test_database
psql (9.3.6)
Type "help" for help.

test_database=> help
You are using psql, the command-line interface to PostgreSQL.
Type:  copyright for distribution terms
       h for help with SQL commands
       ? for help with psql commands
       g or terminate with semicolon to execute query
       q to quit
test_database=>

5.与其他数据库的类比

a.支持大多数的标准SQL.
b.支持复杂查询、外键、多版本并发控制、事务....
c.数据类型和函数十分丰富.

6.连接方式可以用Navicate Premium,当然还有自带的psql类似Oracle的sqlplus.

7.将Oracle存储过程迁移到PostgreSql 上.
PostgreSQL 支持多种过程语言,PostgreSQL原生的过程语言是pl/pgsql,还支持PL/Python,PL/perl等.
这里我们演示PL/pgsql(对原始脚本进行了删减和重命名)

Porcedure in Oracle:

 1 --抽数到结果表
 2   procedure scheme_test_etl(in_scheme_id varchar2,
 3                                 in_bbq       varchar2,
 4                                 table_Prefix varchar2) is
 5     v_error_rows number;
 6     v_row_cnt    number;
 7     v_bbq        varchar2(10);
 8     v_model      varchar2(30);
 9     v_table      varchar2(32);
10     v_sql        varchar2(3000);
11   
12   begin
13     v_bbq   := in_bbq;
14     v_model := table_Prefix;
15   
16     /*临时表数据清理*/
17     execute immediate 'truncate table TEMP_EDQ10_DIM_LEVEL_ANAYS';
18     
19     /*抽数到临时表*/
20     v_sql := 'insert into TEMP_EDQ10_DIM_LEVEL_ANAYS select * from ' ||
21              v_model || '_DIM_LEVEL_ANAYS';
22     execute immediate v_sql;
23 
24     --被检测表信息
25     v_table := v_model || '_checkedtb';
26     execute immediate 'delete from ' || v_table ||
27                       ' t where t.schemeid_ = ' || chr(39) || in_scheme_id ||
28                       chr(39) || ' and t.bbq =' || v_bbq;
29     for c in (select t.PERIOD_ BBQ_,
30                      t.SCHEMEID_,
31                      t.HIERARCHY_, --数据级次
32                      t2.facttableid_, --表名
33                      100 - sum(nvl(DUETABLESCORE_, 0) - nvl(TABLESCORE_, 0)) table_score, --表分数
34                      sum(nvl(t.TOTALCNT_, 0)) TOTALCNT_, --此期此户此规则全部数据行数 ==> 规则检查次数
35                      sum(nvl(t.ERRORCNT_, 0)) ERRORCNT_ --错误数 ==>错误次数
36                 from temp_EDQ10_STATISTICS t, EDQ10_RULES t2
37                where t.ruleid_ = t2.id_
38                group by t.PERIOD_,
39                         t.SCHEMEID_,
40                         t.HIERARCHY_,
41                         t2.facttableid_) loop
42     
43       v_error_rows := get_scheme_error_rows(c.hierarchy_, c.facttableid_); --得到方案错误行数
44       v_row_cnt    := get_scheme_total_rows(c.hierarchy_, c.facttableid_); --得到方案总数据行数
45     
46       v_sql := 'insert into ' || v_table || '
47         (bbq,
48          SCHEMEID_,
49          hierarchy_,
50          checkedtable_score,
51          checkedtable_id,
52          checkedtable_rows,
53          error_rows,
54          checked_times,
55          error_times)
56         select :1,:2,:3,:4,:5,:6,:7,:8,:9 from dual';
57       execute immediate v_sql
58         using c.BBQ_, c.SCHEMEID_, c.HIERARCHY_, c.table_score, c.facttableid_, v_row_cnt, v_error_rows, c.TOTALCNT_, c.ERRORCNT_;
59     end loop;
60     
61     commit;
62   
63   exception
64     when others then
65       dbms_output.put_line(sqlcode || '--' || sqlerrm);
66       rollback;
67   end;
oracle procedure

function in PostgreSQL:

 1 create or replace function DataClaen_ETL.scheme_test_etl(in_scheme_id in varchar,in_bbq in varchar,table_Prefix in varchar) 
 2 returns void as $func$    
 3     declare
 4   --抽数到结果表
 5     v_error_rows numeric;
 6     v_row_cnt    numeric;
 7     v_bbq        varchar(10);
 8     v_model      varchar(30);
 9     v_table      varchar(32);
10     v_sql        text;
11 
12         referrer_keys CURSOR IS
13         select t.period_ bbq,
14                      t.SCHEMEID_,
15                      t.hierarchy_, --数据级次
16                      100 -
17                      sum(t.DUERULESCORE_ - t.RULESCORE_) scheme_score, -- ==>方案得分
18                      sum(t.TOTALCNT_) TOTALCNT_, --此期此户此规则全部数据行数 ==> 规则检查次数
19                      sum(t.ERRORCNT_) error_times, --错误数 ==>错误次数           
20                      count(distinct t.ruleid_) scheme_rule_cnt, --方案规则总数
21                      sum(case
22                            when t.ERRORCNT_ = 0 then
23                             0
24                            else
25                             1
26                          end) error_rule_cnt --错误规则数
27                 from temp_EDQ10_STATISTICS t
28                group by t.period_, t.SCHEMEID_, t.hierarchy_
29                order by t.period_, t.SCHEMEID_, t.hierarchy_;
30   
31   begin
32     v_bbq   := in_bbq;
33     v_model := table_Prefix;
34   
35     /*临时表数据清理*/
36     execute  'truncate table TEMP_EDQ10_DIM_LEVEL_ANAYS';
37     /*抽数到临时表*/
38     v_sql := 'insert into TEMP_EDQ10_DIM_LEVEL_ANAYS select * from ' ||
39              v_model || '_DIM_LEVEL_ANAYS';
40     execute  v_sql;
41     
42     --模型方案总览表 
43     v_table := v_model || '_scheme_vi';
44     v_sql   := 'delete from ' || v_table || ' t where t.schemeid_ = ' ||
45                chr(39) || in_scheme_id || chr(39) || ' and t.PERIOD_ =' ||chr(39)||v_bbq||chr(39);
46 
47     execute  v_sql;
48 
49     for c in referrer_keys loop
50       v_error_rows := dataclaen_etl.get_scheme_error_rows(c.hierarchy_, 'AA'); --得到方案错误行数
51       v_row_cnt    := dataclaen_etl.get_scheme_total_rows(c.hierarchy_, 'AA'); --得到方案总数据行数
52     
53       execute  '
54       insert into ' || v_table || '
55         (PERIOD_,
56          SCHEMEID_,
57          hierarchy_,
58          scheme_score,
59          row_cnt,
60          ERR_ROW_CNT,
61          ruler_checked_times,
62          error_times,
63          scheme_rule_cnt,
64          error_rule_cnt)
65         values ('||chr(39)||c.bbq||chr(39)||' , '||chr(39)||c.SCHEMEID_||chr(39)||' , '||c.hierarchy_||' , '||c.scheme_score||' ,'|| v_row_cnt||' ,'|| v_error_rows||' , '||c.totalcnt_||' , '||c.error_times||' ,'|| c.scheme_rule_cnt||' , '||c.error_rule_cnt||')';
66     end loop;
67   
68 $func$ language plpgsql;
PostgreSQL function

实现方式的差异性:
a.plpgsql没有package的概念(在oracle 中是用package来组织procedure和function的),用schema代替(即创建Schema DataClaen_ETL 而不是package DataClaen_ETL)。
b.PostgreSQL 没有Procedure,但是支持函数,与Oracle的function的功能相同,更厉害的是PostgreSQL的function支持 returns void,这个角度看来function与procedure无异。
c.PLpgsql 中游标必须先声明再使用,不支持Oracle For 循环直接定义的方式。
d.PLpgsql 必须指定函数开始和结束的标识符,且需要指定函数的实现语言(如此示例中 language plpgsql)
e.PostgreSQL 中没有dual伪表。
d.plpgsql 不支持自制事务,不能添加commit

原文地址:https://www.cnblogs.com/Alex-Zeng/p/5249990.html