【greenplum】greenplum的plpgsql:函數,存儲過程,賦值語句,DML語句,靜態語句與動態語句,流程控制語句



--greenplum 的plpgsql
注意:
●greenplum 的plpgsql 與 postgresql 不是完全兼容的。
●plpgsql 不明確界定 函數和存儲過程,“returns void” 表示 存儲過程,“return 數據類型” 表示 函數。
●greenplum中的函數分成3種類型: immutable(不可變更的),stable(穩定的),volatile(易變的)。用戶自定義的函數若沒特別聲明,默認是volatile的。
●plpgsql 不使用 commit,rollback 語句,否則運行時會報錯,但是子程序可以編譯成功即創建成功。
●plpgsql 的動態語句 格式“execute <varchar變量的sql語句>”;plpgsql沒有 execute [into <variable_list>] [using <variable_list>] 的寫法,而ORACLE的動態語句有 execute immediate [into <variable_list>] [using <variable_list>] 的寫法。
●plpgsql 不使用 游標,而是用 for 循環代替。
●plpgsql 的異常信息 變量: sqlstate,sqlerrm。沒有sqlcode。
DB2 的 異常信息 變量:sqlcode,sqlstate,message_text。
ORACLE 的 異常信息 變量:sqlcode,sqlerrm。

 

【greenplum的賦值語句 與 賦值符】
1.賦值語句
select into [from];
說明:可以帶from子句,也可以不帶。
2.賦值符
變量 := 值;

【greenplum的DML語句】
1.select
select into [from] ;
2. insert,update,delete
靜態語句,動態語句

DDL語句:建表,建函數等
動態語句


TCL語句:
注意: plpgsql中使用TCL語句,可以編譯成功,但運行會報錯 ERROR:can not begin/end transactions in PL/pgSQL。

 

【greenplum】的 函數 與 存儲過程

說明:plpgsql 里 函數和存儲過程定義的關鍵字都是function,只是 函數 returns <數據庫類型> ,存儲過程 returns void 。

 

【greenplum 存儲過程】
--建表
create table zzhtest.t_int_tesr(
c1 integer,
c2 integer
) distrobuted by (c1);

select * from zzhtest.t_int_test;

--創建 存儲過程
drop function zzhtest.prc_test(integer,integer);

create or replace function zzhtest.prc_test(
in ii_c1 integer,
in ii_c2 integer
)
returns void as $$ 
begin
insert into zzhtest.t_int_test(ii_c1,ii_c2);
end;
$$ language plpgsql;

--psql調用 存儲過程
select zzhtest.prc_test(1,200); 
select * from zzhtest.t_int_test;

 

【greenlum  函數】
--創建
create function zzhtest.dup(int)
returns integer as $$ select $1 + 1000 $$
language sql;

--psql調用
select * from zzhtest.dup(42);

 

 【greenplum 調用 函數】

1. psql語句
select <schema>.<function_name>(<parameter_list>);
2. plpgsql語句
<variable> := <schema>.<function_name>(<parameter_list>);

【greenplum 調用 存儲過程】
1. psql語句
select <schema>.<function_name>(<parameter_list>);

 

【plpgsql 的流程控制語句】

說明: greenplum子程序中的 流程控制語句 與 oracle 寫法一樣。

1. for 循環 代替 游標(plpgsql中沒有游標) 
--復制表結構
create table zzhtest.t_brand_bak as select * from zzhtest.t_brand where 1=2;
--創建 函數
drop function zzhtest.fnc_test();
create or replace function zzhtest.gnc_test()
returns varchar as $$
declare
rec record;
vv_result varchar(200);
begin
for rec in (select brand_code,brand_name from zzhtest.t_brand ) loop
insert into zzhtest.t_brand_bak values(rec.brand_code,rec.brand_name);
end loop;
vv_result := 'successful';
return vv_result;
exception
when others then
vv_result := substr(sqlstate ||':'|| sqlerrm,1,200); 
end;
$$ language plpgsql;

select zzhtest.fnc_test();
select * from zzhtest.t_brand;
select * from zzhtest.t_brand_bak;
說明: loop variable of loop over rows must be a record or row variable or list of scalar variables。

--2. for i in n1..n2 loop end loop 
drop function zzhtest.fnc_test();
create or replace function zzhtest.gnc_test()
returns integer as $$
declare
vi_sum integer default 0;
begin
for i in 1..100 loop --此處i無需定義
vi_sum := vi_sum + i;
end loop;
return vi_sum;
exception
when others then
return -1;
end;
$$ language plpgsql;

select zzhtest.fnc_test();

--while loop end loop
drop function zzhtest.fnc_test();
create or replace function zzhtest.gnc_test()
returns integer as $$
declare
vi_i integer;
vi_sum integer default 0;
begin
vi_i := 100;
while vi_i > 0 loop 
vi_sum := vi_sum + vi_i;
vi_i := vi_i - 1;
end loop;
return vi_sum;
exception
when others then
return -1;
end;
$$ language plpgsql;

select zzhtest.fnc_test();


--分支 if then elsif then else end if
drop function zzhtest.fnc_test(integer,integer);

create or replace function zzhtest.gnc_test(
in iv_a integer,
in iv_b integer
)
returns varchar as $$
declare
vv_result varchar(10);
begin
if iv_a = iv_b then
vv_result := iv_a ||'與'|| iv_b ||'相等';
elsif iv_a > iv_b then
vv_result := iv_a ||'大於'|| iv_b;
else
vv_result := iv_a ||'小於'|| iv_b;
end if;
return vv_result;
exception
when others then
vv_result := substr(sqlstate ||':'|| sqlerrm,1,200); 
return vv_result;
end;
$$ language plpgsql;

select zzhtest.fnc_test(100,58);
select zzhtest.fnc_test('0100',58);
select zzhtest.fnc_test('a',58);

 

 

【greenplum 的 靜態語句 和 動態語句】
drop function zzhtest.fnc_test(varchar,varchar);

create or replace function zzhtest.fnc_test(
in iv_brand_code varchar,
in iv_brand_name varchar
)
returns varchar as $$
declare vi_cnt integer;
declare vv_sql varchar(100);
declare vv_result varchar(200);
begin
--select into語句
select count(*) into vi_cnt from zzhtest.t_brand where brand_code = upper(iv_brand_code);
--greenplum子程序中沒有 execute into 的寫法
--vv_sql := ' select count(*) from zzhtest.t_brand where brand_code = upper('''||iv_brand_code||''')';
--execute vv_sql into vi_cnt;

if vi_cnt = 0 then
--insert into zzhtest.t_brand values(upper(iv_brand_code),upper(iv_brand_name)); --靜態語句
vv_sql := ' insert into zzhtest.t_brand values(upper('''||iv_brand_code||'''),upper('''||iv_brand_name||'''))';
execute vv_sql; --動態語句
else
--update zzhtest.t_brand set brand_name = upper(iv_brand_name) where brand_code = upper(iv_brand_code); -- 靜態語句
vv_sql := 'update zzhtest.t_brand set brand_name = upper('||quote_literal(iv_brand_name)||') where brand_code = upper('||quote_literal(iv_brand_code)||') ';
execute vv_sql; --動態語句
end if;
vv_result := 'successful';
return vv_result;
exception
when others then
vv_result := substr(sqlstate ||':'|| sqlerrm,1,200); --異常信息
end;
$$ language plpgsql;


select zzhtest.fnc_test('b01','oppo');
select zzhtest.fnc_test('b01','sunxing');
select * from zzhtest.t_brand;
truncate table zzhtest.t_brand;

說明: greenplum 子程序中的'可以用2個'表示,即 '''';而一對'可以用greenplum的函數 quote_literal()處理,以簡化閱讀。

 


免責聲明!

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



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