GBase8s存储过程

存储过程

存储过程中的概要语法

CREATE [DBA] PROCEDURE 过程名(参数[, 参数 [ ,...]])
    RETURNING 子句
  语句块
END PROCEDURE 
DOCUMENT 子句
WITH LISTING IN 文件名;
  • 语法参数说明:
    • 参数

      • [ {IN} | OUT | INOUT ] 参数名称 数据类型

      • 默认是IN,可省略

    • RETURNING子句:

      • 返回数据类型列表
    • 语句块:

      • 有效的SPL语句
    • END PROCEDURE:

      • 结束
    • DECUMENT子句:

      • 对存储过程作的简单说明,可省略
    • WITH LISTING IN 文件名:

      • 说明接受编译器输出信息的文件名,省略不输出

存储过程中的关键语法

声明存储过程:

CREATE PROCEDURE demo_in_parameter(p_in int)

存储过程语句块:

BEGIN ... END

变量定义与赋值:

define v1 int;
let vp = 0;
-- 或者
select tabid into v1 from systables where tabid=1;

创建存储过程:

create procedure 
create function

实例

测试表:

create table compny
  (
    id serial not null ,
    branch varchar(100),
    address varchar(100),
    city varchar(40),
    zipcode char(6),
    phone varchar(18),
    primary key (id)
  );
 
insert into compny values (0,'总部','华苑产业区海泰发展六道6号海泰绿色产业基地J座','天津市西青区','300384','022-58815678');
insert into compny values (0,'北京分公司','太阳宫中路12号太阳宫大厦10层1008室','北京市朝阳区','100102','010-88866866');
insert into compny values (0,'南京分公司','奥体大街69号1栋20层','南京市建邺区','210019','025-87775809');

存储过程实例:

CREATE PROCEDURE read_address(p_branch varchar(100))
   RETURNING varchar(100),varchar(100),char(6);
 
 DEFINE v_branch,v_address varchar(100);
 DEFINE v_zipcode char(6);
 
 SELECT branch, address, zipcode INTO v_branch, v_address, v_zipcode
 FROM compny
 WHERE branch = p_branch;
 
 RETURN v_branch, v_address, v_zipcode;
END PROCEDURE
DOCUMENT '读取分支机构信息,返回分支机构名称、地址及邮编'
WITH LISTING IN '/home/gbase/read_address_sql.lst';

说明:默认情况下,存储过程和默认数据库相关联,如果想指定存储过程创建在某个特定的数据库下,那么在过程名前面加数据库名做前缀。

调用存储过程:

call sp_name[(传参)];
> call read_address('北京分公司');
 
(expression)  北京分公司
(expression)  太阳宫中路12号太阳宫大厦101008(expression)  100102

说明:在存储过程中设置了需要传参的变量p_branch,调用存储过程的时候,通过传参将’北京分公司’赋值给p_branch,然后进行存储过程里的SQL操作。

存储过程体 :

存储过程体包含了在过程调用时必须执行的语句,例如:dml、ddl语句,if-then-else和while语句、声明变量语句等

过程体格式:以begin开始,以end结束(可嵌套)

BEGIN
  BEGIN
    BEGIN
      statements; 
    END
  END
END

注意:每个嵌套块及其中的每条语句,必须以分号结束,表示过程体结束的begin-end块(又叫做复合语句compound statement),则不需要分号。

存储过程的参数

存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:
CREATE PROCEDURE 存储过程名([[{IN} |OUT |INOUT ] 参数名 数据类形...])
IN 输入参数:无关键字表示IN, 表示调用者向过程传入值(传入值可以是字面量或变量)
OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

注意:
1、如果过程没有参数,也必须在过程名后面写上小括号例:
2、确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理
1、in 输入参数
create procedure in_param(p_in int) 
	returning varchar(100);
  define v_in int;
  let v_in = p_in + 1;
  return 'Value of p_in + 1 : ' || v_in;
end procedure;
2、out输出参数
create procedure out_param(out p_out int) 
	returning varchar(100);
  define v_in int;
  let v_in = 1;
  let p_out = v_in + 1;              --p_out是out参数
  return 'Value of v_in : ' || v_in; --返回的是一个字符串
end procedure;

-- 调用out_param
create procedure call_out_param() 
	returning varchar(100);
  define v_in int;
  define v_rc varchar(100);
  let v_in = -1;
  call out_param(p_out = v_in) returning v_rc;  --这个函数没有输入,只有out参数给到给到一个变量。
  let v_rc = v_rc || ' , Value of p_out : ' || v_in;
  return v_rc;
end procedure;
> call call_out_param();
(expression)  Value of v_in : 1 , Value of p_out : 2
1 row(s) retrieved.

说明: call_out_param中, 作为p_out的参数的v_in变量需要指定的默认值(虽然无意义),值在存储过程out_param中改变。

3、inout输入输出参数
create procedure inout_param(inout p_inout int) 
	returning varchar(100);
  let p_inout = p_inout + 1;
  return 'Value of p_inout : ' || p_inout;
end procedure;

-- 调用inout_param
create procedure call_inout_param() 
	returning varchar(100);
  define v_in int;
  define v_rc varchar(100);
  let v_in = 1;
  call inout_param(p_inout = v_in) returning v_rc;
  let v_rc = v_rc || ' , Value of p_inout : ' || v_in;
  return v_rc;
end procedure;
> call call_inout_param();
(expression)  Value of p_inout : 2 , Value of p_inout : 2
1 row(s) retrieved.

call_inout_param中,作为p_inout参数的v_in变量需要指定值,值在存储过程inout_param中改变。

变量

1. 变量定义

局部变量声明一定要放在存储过程体的开始:
DEFINE variable_name [,variable_name…] datatype ;
其中,datatype 为数据类型,如: int, float, date,varchar(length)
定义TEXT 或BYTE 类型变量时, 需在其变量前加关键字REFERENCES
可以使用LIKE定义与字段类型一致的数据类型

DEFINE v_x INT;
DEFINE v_name CHAR(15);
DEFINE v_this_day DATETIME YEAR TO DAY;
DEFINE v_tttt REFERENCES TEXT;
DEFINE v_bbb REFERENCES BYTE;
DEFINE v_customer LIKE orders.customer_num;

全局变量声明时需要指定默认值 .

2. 变量赋值

利用LET 语句 (LET 变量名 = 表达式值 [,variable_name = expression …])
利用SELECT … INTO 语句
利用CALL … RETURNING 语句
利用EXECUTE PROCEDURE … INTO 语句

LET a, b=c, d;
LET a, b=(SELECT empname, empno FROM emp WHERE empno=125);
 
SELECT empname INTO v_name FROM emp WHERE empno=120;
 
CALL read_address('北京分公司') RETURNING v_branch, v_address, v_zipcode;
 
EXECUTE PROCEDURE read_address('北京分公司') INTO v_branch, v_address, v_zipcode;

四、注释

存储过程可使用两种风格的注释
两个横杆–:该风格一般用于单行注释。
c 风格/**/: 一般用于多行注释。

五、存储过程的调用

用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。具体的调用方法可以参看上面的例子。

存储过程的查询

使用dbschema实用工具查询存储过程信息语法:

dbschema -d 数据库名 -f 过程名 

或者使用SQL语句查询

select data
from sysprocedures, sysprocbody
where datakey = 'T'
and sysprocedures.procname = 'in_param'        -- in_param 为存储过程名字
and sysprocedures.procid = sysprocbody.procid;
存储过程的删除

删除一个存储过程比较简单,和删除表一样:DROPP ROCEDURE [IF EXISTS] 存储过程名称

存储过程的控制语句

(1). 变量作用域

内部的变量在其作用域范围内享有更高的优先权,当执行到 end。变量时,内部变量消失,此时已经在其作用域外,变量不再可见了,应为在存储过程外再也不能找到这个申明的变量。

create procedure proc1() returning varchar(128);
  define v_rc varchar(128);
  let v_rc = "";
  begin  -- 层1
    define v_1 int;
    let v_1 = 1111;      
    begin  -- 层2
    define v_1 int;
      let v_1 = 2222;
      let v_rc = v_rc || " 层二 v_1的值是:" || v_1;
    end
    let v_rc = v_rc || " 层一 v_1的值是:" || v_1; 
  end
  return v_rc;
end procedure;

层一的变量v_1不因层二的变量v_1改变。

(2). 条件语句

1)、if … then … elif … then … else … end if 语句

create procedure proc2(p_in int) returning varchar(128);
  define v_rc varchar(128);
  let v_rc = "";
  if p_in = 0 then
    let v_rc = 'p_in的值是0';
  elif p_in = 1 then             -- 可以有多个elif ... then
    let v_rc = 'p_in的值是1';
  else
    let v_rc = 'p_in的值是其它';
  end if;
  return v_rc;
end procedure;

2)、case … when … then … else … end case语句:

create procedure proc3(p_in int) returning varchar(128);
  define v_rc varchar(128);
  let v_rc = "";
  case p_in
    when 0 then
      let v_rc = 'p_in的值是0';
    when 1 then
      let v_rc = 'p_in的值是1';
    else
      let v_rc = 'p_in的值是其它';
  end case;
  return v_rc;
end procedure;

(3). 循环语句

1)、 while ··· end while语句
create procedure proc4(p_in int) returning varchar(128);
  define v_rc varchar(128);
  let v_rc = "";
  while p_in < 6
    let v_rc = v_rc || '当前p_in的值为:' || p_in || '\n ';
    let p_in = p_in + 1;
  end while;
  return v_rc;
end procedure;
2)、for … end for语句
create procedure proc5(p_in int) returning varchar(128);
  define v_rc varchar(128);
  define i int;
  let v_rc = "";
  for i = p_in to 5
    let v_rc = v_rc || '当前i的值为:' || i || '\n ';
  end for;
  return v_rc;
end procedure;
3)、loop ··· end loop语句

loop 循环不需要初始条件,这点和 while 循环相似, exit when语句的意义是离开循环。

create procedure proc6(p_in int) returning varchar(128);
  define v_rc varchar(128);
  define i int;
  let v_rc = "";
  let i = p_in;
  loop
    let i = i + 1;
    let v_rc = v_rc || '当前i的值为:' || i || '\n ';
    exit when i = 5;
  end loop;
  return v_rc;
end procedure;
4)、for … loop … end loop语句
create procedure proc7(p_in int) returning varchar(128);
  define v_rc varchar(128);
  define i int;
  let v_rc = "";
  for i in (p_in to 6) loop
    let v_rc = v_rc || '当前i的值为:' || i || '\n ';
    exit when i = 5;
  end loop;
  return v_rc;
end procedure;
5)、while … loop … end loop语句
create procedure proc8(p_in int) returning varchar(128);
  define v_rc varchar(128);
  define i int;
  let v_rc = "";
  let i = p_in;
  while(i<6) loop
    let v_rc = v_rc || '当前i的值为:' || i || '\n ';
    exit when i = 5;
    let i = i + 1;
  end loop;
  return v_rc;
end procedure;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值