移植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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM