————————————————
版權聲明:本文爲CSDN博主「尚雲峯」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u011165335/article/details/99895650
在pg裏面,只有function
1.刪除函數 函數名+參數簽名
drop FUNCTION if exists HelloWorld2(varchar);
2.CREATE OR REPLACE FUNCTION 不允許你修改一個現有函數的返回類型。
– 要做這些事情,你必須刪除並重新創建函數。
–LANGUAGE plpgsql yelowbick只有過程,跟pgsql剛好相反
–入參:anyelement 基本類型 表類型 遊標
–返回:基本類型,記錄類型,遊標,json,table類型,數組
--塊language plpgsql可以註釋掉 方便用來測試
do --language plpgsql
$$
begin
raise notice 'ok';
end;
$$;
3.行對象row
select * from dept;
SELECT ROW(‘10’, ‘aaa’, ‘hhhh’)::dept;
– 記錄變量record類似於行類型變量,但是它們沒有預定義的結構,
– 只能通過SELECT或FOR命令來獲取實際的行結構,因此記錄變量在被初始化之前無法訪問,否則將引發運行時錯誤。
–注:RECORD不是真正的數據類型,只是一個佔位符。
4.LANGUAGE SQL
-- LANGUAGE SQL 簡單的DML語句
create or replace FUNCTION func_get() RETURNS int AS
$$
select 1;
$$ LANGUAGE SQL;
select * from func_get();
create or replace function add_two(int,int)
returns int
as
$$
select $1+$2;
$$ LANGUAGE sql;
select * from add_two(1,2);
--returning返回更新前的值
drop function update_emp(varchar);
create or replace function update_emp(varchar)
returns varchar
as
$$
update emp set ename=$1||'ysy' where ename=$1
returning ename;
$$ LANGUAGE sql;
select * from update_emp('SMITH');
--複合類型
create or replace function sel_emp(emp)
returns varchar
as
$$
select $1.ename;
$$ LANGUAGE sql;
select sel_emp(e.*) from emp e;
--輸出類型 這裏等價於add_two
CREATE FUNCTION add_two2 (IN x int, IN y int, OUT sum int) AS $$
SELECT $1 + $2*2;
$$ LANGUAGE SQL;
CREATE FUNCTION add_two3 (IN x int, IN y int, OUT sum1 int,out sum2 int) AS
$$
SELECT $1 + $2*2,$1 + $2;
$$ LANGUAGE SQL;
select * from add_two3(1,2);
--返回集合-----------------------------------------
-- 類型爲emp,默認之返回第一條記錄
CREATE FUNCTION getfoo1() RETURNS emp AS $$
SELECT * FROM emp ;
$$ LANGUAGE SQL;
select * from getfoo1();
--如果要全部返回setof table
CREATE FUNCTION getfoo2() RETURNS setof emp AS $$
SELECT * FROM emp ;
$$ LANGUAGE SQL;
select * from getfoo2();
--可以訪問指定列
select (getfoo2()).ename;
drop function getfoo2_1;
--可以指定返回表的具體字段類型
create or replace function getfoo2_1() RETURNS emp.ename%type AS $$
SELECT ename FROM emp ;
$$ LANGUAGE SQL;
select * from getfoo2_1();
--可以返回記錄類型
create or replace function getfoo3() RETURNS record AS $$
SELECT empno,ename FROM emp ;
$$ LANGUAGE SQL;
select getfoo3() ;
--如何訪問記錄類型結果集呢 類型要一致,這個聲明確實有點不方便
select t.ename from getfoo3() t (empno integer,ename varchar);
--自定義返回類型
create type rec_type as (empno int,ename varchar);
create or replace function getfoo4() RETURNS rec_type AS $$
SELECT empno,ename FROM emp ;
$$ LANGUAGE SQL;
--這裏type裏面指定了,不需要聲明
select t.ename from getfoo4() t ;
--多態
CREATE FUNCTION make_array(anyelement, anyelement) RETURNS anyarray AS $$
SELECT ARRAY[$1, $2];
$$ LANGUAGE SQL;
select * from make_array(1,1);
--字符要指定類型
select * from make_array('a'::text,'n'::text);
-- 如果PL/pgSQL函數的返回類型爲多態類型(anyelement或anyarray),那麼函數就會創建一個特殊的參數:$0。
-- 我們仍然可以爲該變量設置別名。
create or replace function add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
result ALIAS FOR $0;
BEGIN
result := v1 + v2 + v3;
RETURN result;
--RETURN (v1 + v2 + v3); --等價
END;
$$ LANGUAGE plpgsql;
select * from add_three_values(1,2,3);
--重載
CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(int, varchar) RETURNS ...
5.language plpgsql
返回集合類型和json的方式如下:
-- language plpgsql
--返回record
create or replace function getRecord()
returns record
as
$$
declare
v_arr record;
begin
v_arr := ('aaa'::varchar,'bbb'::varchar);
return v_arr;
end ;
$$ language plpgsql;
select t.* from getRecord() t (a varchar,b varchar);
--返回數組
create or replace function getArr()
returns int[]
as
$$
declare
v_arr int[];
begin
v_arr := array [1,2];
return v_arr;
end ;
$$ language plpgsql;
--返回json
create or replace function getJson()
returns json
as
$$
declare
v_arr json;
begin
v_arr := '{"name":"李易峯","sex":"男"}';
return v_arr;
end ;
$$ language plpgsql;
--測試
do
$$
declare
v_rec1 varchar;
v_rec2 varchar;
v_arr int[];
v_json json;
begin
--record
select t.* into v_rec1,v_rec2 from getRecord() t (a varchar,b varchar);
raise notice 'record=,%,%',v_rec1,v_rec2;
--arr
v_arr:=getArr();
raise notice 'arr=,%',v_arr[1];
v_json:=getJson();
raise notice 'json=,%',v_json->>'name';
end;
$$;
6.遊標操作
--遊標操作
--返回所有結果集
create or replace function getRcord() RETURNS setof record AS $$
declare
rec record;
--oracle cursor c_emp is ...
c_emp cursor for select ename from emp;
--pg 不存在c_emp%rowType;這種類型,用record來接受
begin
for rec in c_emp loop
--將當前行的結果集插入rec
return next rec;
end loop;
return ;
end;
$$ language plpgsql;
--需要聲明
select * from getRcord() t (ename varchar);
create or replace function getRcord1_2(refcursor) RETURNS setof refcursor AS $$
declare
rec record;
ref alias for $1;
begin
open ref for select * from emp;
return next ref;
end;
$$ language plpgsql;
select getRcord1_2('a'::refcursor);
--返回text 方式1
create or replace function getRcord2() RETURNS text AS $$
declare
rec record;
v_text text;
c_emp cursor for select * from emp;
begin
v_text:='';
open c_emp;
loop
fetch c_emp into rec;
exit when not FOUND;
v_text:=v_text||','||rec.ename;
end loop;
close c_emp;
return v_text;
end;
$$ language plpgsql;
select getRcord2();
--返回text 方式2
drop function getref;
create or replace function getRcord3() RETURNS text AS $$
declare
ref refcursor;
v_rec record;
v_text text:='';
begin
--open ref for SELECT empno,ename FROM emp ;
open ref for execute 'SELECT empno,ename FROM emp' ;
--動態遊標,只能loop循環,這點跟oracle是一樣的
loop
fetch ref into v_rec;
exit when not found;
v_text:=v_text||','||v_rec.ename;
end loop;
close ref;
return v_text;
exception when others
then
raise exception 'error,%',SQLERRM;
end;
$$ language plpgsql;
select * from getRcord3();
--動態遊標
/*PL/pgSQL 函數可以向調用者返回遊標。 這個功能用於從函數裏返回多行或多列。要想這麼做的時候, 該函數打開遊標並且把該遊標的名字返回給調用者。 調用者然後從遊標裏FETCH行。 遊標可以由調用者關閉,或者是在事務結束的時候自動關閉。
函數返回的遊標名可以由調用者聲明或者自動生成。 要聲明一個信使的名字,只要再打開遊標之前,給 refcursor 變量賦予一個字串就可以了。 refcursor 變量的字串值將被 OPEN 當作下層的信使的名字使用。 不過,如果 refcursor 變量是空,那麼 OPEN 將自動生成一個和現有信使不衝突的名字, 然後將它賦予 refcursor 變量。
注意: 一個綁定的遊標變量其名字初始化爲對應的字串值,因此信使的名字和遊標變量名同名, 除非程序員再打開遊標之前通過賦值覆蓋了這個名字。但是一個未綁定的遊標變量初始化的時候缺省是空, 因此它會收到一個自動生成的唯一的名字,除非被覆蓋。
下面的例子顯示了一個調用者聲明遊標名字的方法:*/
create or replace FUNCTION ger_ref(refcursor) RETURNS refcursor AS
$$
BEGIN
OPEN $1 FOR SELECT ename FROM emp;
RETURN $1;
END;
$$ LANGUAGE plpgsql;
--只能用一次那個遊標名,用
BEGIN;
SELECT ger_ref('funccursor');
FETCH ALL IN funccursor;
COMMIT;
--下面的例子使用了自動生成的遊標名:
drop FUNCTION if exists ger_ref2;
create or replace FUNCTION ger_ref2() RETURNS refcursor AS
$$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR SELECT ename FROM emp;
RETURN ref;
END;
$$ LANGUAGE plpgsql;
BEGIN;
SELECT ger_ref2();
FETCH ALL IN "<unnamed portal 1>";
COMMIT;
7.函數的調用
--函數的調用
-- yellow brick 是call和execute
-- select into 對於返回結果多行的,指揮取一行,如果結果爲空,不會報錯,跟oracle不一樣
drop function into_test;
create or replace function into_test()
returns text as
$$
declare
v_name emp.ename%type;
begin
select e.ename into v_name from emp e;
if found then
raise notice 'ename=%',v_name;
end if;
return 'ok';
end;
$$
language plpgsql;
select into_test();
do $$
declare
v_text text;
begin
--方式0
--v_text:=into_test();
--方式1
--execute 'into_test()';
--方式2 忽略返回值
--perform into_test();
-- 錯誤select into_test();
end
$$;
8.pgsql的批量操作
https://yq.aliyun.com/articles/54786?spm=a2c4e.11153940.0.0.28e2231f3pNJsx
https://yq.aliyun.com/articles/74420?do=login&accounttraceid=b0fcec2d-bb75-4f55-89a2-81fbcfb21110&do=login
————————————————
版權聲明:本文爲CSDN博主「尚雲峯」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/u011165335/article/details/99895650