虽然现在postgresql的使用率不错,但是现在关于它的教程还是很少,而教程中对于存储过程的讲解也不详细,今天就自己的使用经验说一说。
创建存储过程很简单,create or replace function test(),当然,你如果这样写:create function test()也可以,但如果test()已存在就会报错,第一种写法是创建或覆盖,就是无论有没有都创建test()。这个是不带参数的,那如果带参数的存储过程呢?这样:create or replace function test(name varchar),存储过程参数的数据类型要放在参数名的后面,现在来创建一个简单的存储过程。
create or replace function test(name varchar) returns varhcar as
$$
declare
str varchar;
str2 varchar;
begin
str = name;
str2 = name || ' is ' || $1;
return str2;
end
$$
language plpgsql;
执行它:select test('postgresql'),返回的是一个字符串’postgresql is postgresql',这里对这个存储过程介绍一下,首先returns varchar定义一个返回类型,说明返回varchar类型的数据,$$符号把存储过程包围起来,更便于存储过程的识别,declare是声明变量,而函数体都在begin和end之间,name是代表参数name,而$1也是代表name,它是指存储过程的第一个参数,$2是指第二个参数,在存储过程里,字符串的相加用的||,中间要用空格,如果是常量,那要用两个'来包含起来,如果我需要字符',那怎么办?那还是用两个'包含起来,注意,'是关键符号,所以要用两个'来表示一个',所以用四个'可以表示一个'字符。
现在来说一说在存储过程里对数据库的一些操作。
第一:select into
使用select into可以查询数据库,看一个例子:
create or replace function selectinto() returns varchar as
$$
declare
name varchar;
begin
select into name num from test;
return name;
end
$$
language plpgsql;
把表test里的num赋给变量name,然后返回,这里返回的是第一条记录的num。
如果查询语句里有未知的参数,那要怎么办?这样用select into就不能满足要求了。把上面的存储过程修改一下:
create or replace function selectinto(num int4) returns varchar as
$$
declare
sql varchar;
begin
sql = 'select * from test where num=' || num;
execute sql;
end
$$
language plpgsql;
当要查询所有记录,然后循环取的想要的值,这要用到记录类型record.
create or replace function selectinto(num int4) returns varchar as
$$
declare
sql varchar;
str varchar;
re record;
begin
sql = 'select name from test where num=' || num;
for re in execute sql loop
str = str + re.name;
end loop;
return str;
end
$$
language plpgsql;
在for循环里是可以嵌套for循环的,省力一点,下面贴个自己写的存储过程:
create or replace function checknum(lpbh varchar,zzxsid varchar,xqr varchar,qzrs int4,xql int4,id int4) returns varchar as
$$
declare
s varchar; ----用来接收存储过程insert_checknum的返回结果
dt date; ----需求日
dt2 date; ----起排日
dt3 date; ----今天的日期
dt4 date; ----排产日
res record;
a int4; ----某个制造形式ID的产能
i int4; ----起排日到今天的天数
j int4; ----从起排日开始算某个只在形式ID的产能累计
sql varchar;
begin
----如果传入的参数有一个为空,则返回0
if(lpbh is null or zzxsid is null or xqr is null or qzrs is null or xql is null or id is null) then
return 0;
end if;
dt = $3;
dt2 = dt - $4 - 1;
dt3 = now();
dt4 = dt2;
i = dt2 - dt3;
j = 0;
----查询某个制造形式ID的产能
sql = 'select fld_abm26563 from abm4045 where fld_abm26561=' || '''' || zzxsid ||'''';
for res in execute sql loop
a = res.fld_abm26563;
end loop;
for n in 1..i loop
j = j + a;
----查询产能记录单里有没有和dt4对应的产能记录数据
sql = 'select * from abm4047 where fld_abm26579=' || '''' || dt4 || ''' and fld_abm26583=' || '''' || zzxsid || '''';
for res in execute sql loop
if(res.fld_abm26584 is not null) then
j = j - res.fld_abm26584;
end if;
if(res.fld_abm26585 is not null) then
j = j + res.fld_abm26585;
end if;
end loop;
----查询临时产能记录表temprecord里有没有和当天对应的产能记录
sql = 'select * from temprecord where pcr=' || '''' || dt4 || ''' and zzxsid=' || '''' || zzxsid || ''' and id=' || id;
for res in execute sql loop
if(res.pcl is not null) then
j = j - res.pcl;
end if;
end loop;
dt4 = dt2 - n;
----如果累计产能已能满足需求量,那么返回排产日
if(j>=xql) then
s = insert_checknum(lpbh,zzxsid,xqr,qzrs,xql,id);
return dt4 + 1;
end if;
end loop;
return 0;
end
$$
language plpgsql;
$$
declare
s varchar; ----用来接收存储过程insert_checknum的返回结果
dt date; ----需求日
dt2 date; ----起排日
dt3 date; ----今天的日期
dt4 date; ----排产日
res record;
a int4; ----某个制造形式ID的产能
i int4; ----起排日到今天的天数
j int4; ----从起排日开始算某个只在形式ID的产能累计
sql varchar;
begin
----如果传入的参数有一个为空,则返回0
if(lpbh is null or zzxsid is null or xqr is null or qzrs is null or xql is null or id is null) then
return 0;
end if;
dt = $3;
dt2 = dt - $4 - 1;
dt3 = now();
dt4 = dt2;
i = dt2 - dt3;
j = 0;
----查询某个制造形式ID的产能
sql = 'select fld_abm26563 from abm4045 where fld_abm26561=' || '''' || zzxsid ||'''';
for res in execute sql loop
a = res.fld_abm26563;
end loop;
for n in 1..i loop
j = j + a;
----查询产能记录单里有没有和dt4对应的产能记录数据
sql = 'select * from abm4047 where fld_abm26579=' || '''' || dt4 || ''' and fld_abm26583=' || '''' || zzxsid || '''';
for res in execute sql loop
if(res.fld_abm26584 is not null) then
j = j - res.fld_abm26584;
end if;
if(res.fld_abm26585 is not null) then
j = j + res.fld_abm26585;
end if;
end loop;
----查询临时产能记录表temprecord里有没有和当天对应的产能记录
sql = 'select * from temprecord where pcr=' || '''' || dt4 || ''' and zzxsid=' || '''' || zzxsid || ''' and id=' || id;
for res in execute sql loop
if(res.pcl is not null) then
j = j - res.pcl;
end if;
end loop;
dt4 = dt2 - n;
----如果累计产能已能满足需求量,那么返回排产日
if(j>=xql) then
s = insert_checknum(lpbh,zzxsid,xqr,qzrs,xql,id);
return dt4 + 1;
end if;
end loop;
return 0;
end
$$
language plpgsql;
这个存储过程里调用了另一个存储过程insert_checknum(),这里insert_checknum的代码没有贴出来,这里是用做一个存储过程怎么调用另一个存储过程的例子。