在oracle中,函数和存储过程是经常使用到的,并且有所区别;而postgresql中函数和存储过程都是相同定义的。
Oracle
(存储过程)
1.定义:定义存储过程的关键字为procedure。
2.创建存储过程
create or replace procedure 存储过程名(参数1 类型,参数2 out 类型……)
as
变量名 类型;
begin
程序代码体
end;
例:
(无参数)
create or replace procedure p1
--or replace代表创建该存储过程时,若存储名存在,则替换原存储过程,重新创建
--无参数列表时,不需要写()
as
begin
dbms_output.put_line('hello world');
end;
(有参有返)
create or replace procedure p2 (name in varchar2,age int,msg out varchar2)
--参数列表中,声明变量类型时切记不能写大小,只写类型名即可,例如参数列表中的name变量的声明
--参数列表中,输入参数用in表示,输出参数用out表示,不写时默认为输入参数。
--输入参数不能携带值出去,输出参数不能携带值进来,当既想携带值进来,又想携带值出去,可以用in out
as
begin
msg:='姓名'||name||',年龄'||age;
end;
总结:
1.创建存储过程的关键字为procedure。
2.传参列表中的参数可以用in,out,in out修饰,参数类型一定不能写大小。列表中可以有多个输入输出参数。
3.存储过程中定义的参数列表不需要用declare声明,声明参数类型时需要写大小的一定要带上大小。
4.as可以用is替换。
5.调用带输出参数的过程必须要声明变量来接收输出参数值。
6.执行存储过程有两种方式,一种是使用execute,另一种是用begin和end包住。
(函数)
1.定义:定义函数的关键字为function。
2.创建函数
create or replace function f1
returnvarchar
--必须有返回值,且声明返回值类型时不需要加大小
as
msg varchar(50);
begin
msg :='hello world';
returnmsg;
end;
总结:
1.定义函数的关键字为function 。
2.必须有返回值,且声明返回值类型时不需要加大小。
3.函数中定义的参数列表不需要用declare声明,声明参数类型时需要写大小的一定要带上大小。
4.as可以用is替换。
5.执行存储过程有两种方式,一种是使用select,另一种是用begin和end包住。
(Oracle存储过程与存储函数的区别)
不同点:
1.存储过程定义关键字用procedure,函数定义用function。
2.存储过程中不能用return返回值,但函数中可以,而且函数中必须有return子句。
3.执行方式略有不同,存储过程的执行方式有两种(1.使用execute2.使用begin和end),函数除了存储过程的两种方式外,还可以当做表达式使用,例如放在select中(select f1() form dual;)。
Postgresql
postgresql则将函数和存储过程合为一体,不再明确区分存储过程与函数。
1.定义:定义函数(存储过程 )的关键字为function。
2.创建
Create or replace function 过程名(参数名 参数类型,…..)
returns 返回值类型
as
$body$
Declare
变量名变量类型;
Begin
return 变量名; //存储过程中的返回语句
End;
$body$
Language plpgsql;
例:
CREATE OR REPLACE FUNCTION public.udf_station_in_step5_new()
RETURNS void AS
$BODY$
DECLARE
i integer := 0;
tmp_reportdate timestamp ARRAY[100];
res_slno integer ARRAY[100];
res_reportdate timestamp ARRAY[100];
v_cur_slno integer;
v_cur_reportdate timestamp;
v_sql varchar(500);
cur_list cursor for select slno, reportdate from ods_t_station_in_single order by reportdate;
begin
open cur_list;
fetch cur_list into v_cur_slno, v_cur_reportdate;
while found loop
i := i+1;
tmp_slno := v_cur_slno;
tmp_reportdate[i] := v_cur_reportdate;
fetch cur_list into v_cur_slno, v_cur_reportdate;
while found loop
if v_cur_slno > tmp_slno and v_cur_slno < tmp_slno+10 then
i := i+1;
tmp_slno := v_cur_slno;
tmp_reportdate[i] := v_cur_reportdate;
fetch cur_list into v_cur_slno, v_cur_reportdate;
else
if res_reportdate is null or array_length(tmp_reportdate,1) > array_length(res_reportdate,1) then
res_reportdate := tmp_reportdate;
end if;
i := 0;
tmp_reportdate := null;
exit;
end if;
end loop;
end loop;
close cur_list;
--根据最长的序列挑选出最可能正确的数据
execute 'delete from ods_t_station_in_single2';
if(res_reportdate is not null) then
for i in 1 .. array_length(res_reportdate,1) loop
v_sql := 'insert into ods_t_station_in_single2 select * from ods_t_station_in_single where reportdate ='''||res_reportdate[i]||'''';
execute v_sql;
end loop;
end if;
execute 'delete from ods_t_station_in_single';
insert into ods_t_station_in_single select * from ods_t_station_in_single2 order by reportdate;
execute 'delete from ods_t_station_in_single2';
exception
when QUERY_CANCELED then
raise 'udf_station_in_step5(0)';
commit;
end;
$BODY$
LANGUAGE plpgsql;
总结
1.必须有有returns(注意是returns不是return)子句,无返回值时returns viod
2.执行时,有返回值用select,无返回值时用perform
3.必须指定语言LANGUAGE
网友评论