1、简介
        存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
        存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。
 
2、重要概念和疑问解答
        1)何谓informix中的SPL?
        SPL(Stored Procedure Language)是informix中提供的一种提供流程控制(分支和循环)的SQL。它包括SPL过程(没有返回值)和SPL函数(有返回值)。SPL将在创建的时候被解析和优化,它以可执行的方式保存在system catalog表中。
        2)使用SPL为什么会改善性能?
        i)因为它运行在informix引擎中,所以减少了I/O;
        ii)降低了应用的复杂性;
        iii)对频率较高的重复操作使用更好。
        3)SPL的灵活性表现在哪些部分?
        i)它可在其它SQL语法中被调用;
        ii)它也可以在触发器中使用;
        iii)可在SQL中添加流程控制;
        iv)很容易维护。
       4)SPL的参数
       i)可以传递很多个参数;
       ii)SPL的参数的最大限制是32K;
       iii)除了如下两种外可以是任何一种SQL数据类型:
             Serial/Serial8
             Text/Byte (能够使用REFERENCES关键字传递)。
       iv)能够使用很复杂或者用户自定义的数据类型;
       v)可以通过default为参数指定默认值。
       5)SPL函数的返回值
       i)可以使用RETURNING或RETURNS关键字定义返回值的返回类型;
       ii)除了如下两种数据类型外可以为任何数据类型:
            Serial/Serial8
            Text/Byte (可以使用REFERENCES关键字传递)。
       iii)在过程体内必须至少有一个return语句;
       iv)可以为返回值取一个名称。
例如:
CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
RETURNING INTEGER AS comp_res;
      6)SPL的重载
      可定义多个具有相同名字的SPL函数;例如如下SPL函数虽然名称相同,但是参数类型或各不相同:
CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
CREATE FUNCTION val_comp (val1 CHAR(25), val2 CHAR(25))
CREATE FUNCTION val_comp (val1 DECIMAL, val2 DECIMAL)
 
     可使用SPECIFIC关键字指定SPL函数的简短的、独一无二的被重载的SPL的函数的名称。这个名字在数据库中是唯一的。
例如:
CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER) SPECIFIC int_comp
CREATE FUNCTION val_comp (val1 CHAR(25), val2 CHAR(25)) SPECIFIC string_comp
CREATE FUNCTION val_comp (val1 DECIMAL, val2 DECIMAL) SPECIFIC dec_comp
     7)何谓语句块?
     i)语句块是一组SPL或SQL语句;
     ii)隐式的语句块包含在CREATE PROCEDURE/FUNCTION和END PROCEDURE/FUNCITON之间;
     iii)可使用BEGIN和END来显式的知名内嵌在另一个语句块中的语句块,例如:
CREATE PROCEDURE myproc1() -- 隐式的语句块的开始
DEFINE x INT;
LET x = 15;
INSERT INTO table1 VALUES (x, 'amigo');
BEGIN -- 显式的语句块的开始
DEFINE y INT;
LET y = 16;
INSERT INTO table1 VALUES ( y, 'xingxing');
END -- 显式的语句块的结束
END PROCEDURE; -- 隐式的语句块的结束
      8)如何定义变量?
      i)是语句块中使用DEFINE定义变量;
      ii)变量在内存中,而不是在数据库中保存;
      iii)有本地变量和全局变量两种;
      iv)变量可以是除了如下两种类型之外的任何一种SQL数据类型和扩展类型:
             Serial/Serial8
             Text/Byte (可以使用REFERENCES关键字来声明)。
      定义变量举例如下:
DEFINE x, y INT; -- 内建的数据类型
DEFINE p person_type; -- 用户自定义的数据类型person_type
DEFINE mymusic REFERENCES BYTE; -- 使用REFERENCES关键字定义BYTE类型
      9)本地变量和全局变量比较
      本地变量:
      i)本地变量值在SPL中有效;
      ii)在SPL函数或过程结束后就被复位;
      iii)它不能有默认值;
      iv)它的作用域是在它定义的语句块中,或者任何内嵌语句块中;
      v)本地变量能够被重新定义在另一个语句块中。
     下面来看一个本地变量的实例:
CREATE PROCEDURE local_scope()
DEFINE x,y,z INT;
LET x = 5;
LET y = 10;
LET z = x + y; -- z等于15
BEGIN
  DEFINE x, q INT; -- x被重新定义
  DEFINE z CHAR(5); -- z被重新定义
  LET x = 100;
  LET q = x + y; -- q=110
  LET z = 'amigo'; -- 给z设置了一个新的值
END
LET y = x; -- y等于5
LET x = z; -- z的值是15,而不是amigo
   END PROCEDURE;
     全局变量:
     i)在相同数据库中使用相同的用户会话的地方都能得到全局变量的值;
     ii)必须有一个默认值;
     iii)必须在每一个要使用它的SPL函数或过程中定义;
     iv)不能是一个集合变量。
     例如如下定义了两个SPL函数,名称分别为func1和func2,func1参考语句如下:
CREATE FUNCTION func1() RETURNING INT;
DEFINE GLOBAL gvar INT DEFAULT 2;
LET gvar = gvar + 1;
RETURN gvar;
END FUNCTION;

func2参考语句如下:

CREATE FUNCTION func2()RETURNING INT;
DEFINE GLOBAL gvar INT DEFAULT 5;
LET gvar = gvar + 1;
RETURN gvar;
END FUNCTION;

如果执行两者的顺序如下:

EXECUTE FUNCTION func1();
EXECUTE FUNCTION func2();
     则执行完第一句后,gvar被设置了默认值2,且执行了加1的操作,所以第一句执行完毕后gvar的值为3.
     接着执行第二句,第这次不在设置gvar的默认值,因此在3的基础上再执行了加1操作,执行完毕后gvar的值为4.
     若执行两者的顺序如下:
EXECUTE FUNCTION func2();
EXECUTE FUNCTION func1();
     则执行完第一句后,gvar被设置了默认值5,且执行了加1的操作,所以第一句执行完毕后gvar的值为6.
     接着执行第二句,第这次不在设置gvar的默认值,因此在6的基础上再执行了加1操作,执行完毕后gvar的值为7.
     10)给变量赋值
     i)使用一个未定义的变量将会报错;
     ii)给已定义的变量赋值的方法:
           * 使用LET语句直接给变量赋初值,参考语句如下:
      LET <变量> = <有效的表达式或函数名>;

*使用SELET INTO语句将查询到的结果给变量赋值,参考语句如下:

      SELECT … INTO <变量> FROM …;

*使用CALL...RETURNING语句将返回结果赋给变量,参考语句如下:

       CALL … RETURNING <变量>;

*使用EXECUTE FUNCTION INTO语句,将返回结果赋给变量,参考语句如下:

       EXECUTE FUNCTION … INTO <变量>;
 
3、语法
     1)创建SPL过程
CREATE PROCEDURE name (parameter list) SPECIFIC specific_name
… {语句块}
END PROCEDURE;

例如,在下面的实例中创建了一个名为set_status的存储过程,可传入myid和mystatus两个参数,在这个存储过程中,对item_inventory表进行update操作,id字段满足myid的记录将status字段更新为mystatus。参考语句如下:

CREATE PROCEDURE set_status (myid INTEGER DEFAULT 0, mystatus CHAR(25))
UPDATE item_inventory SET status = mystatus WHERE id = myid;
END PROCEDURE;

2)创建SPL函数

CREATE FUNCTION name (parameter list)
RETURNING list SPECIFIC specific_name
… {语句块}
END FUNCTION;

例如,创建一个名为val_comp的SPL函数,可传入val1和val2两个参数,在该函数中,比较这两个变量,如果两者相等,返回0,否则返回1。参考语句如下:

CREATE FUNCTION val_comp (val1 INTEGER, val2 INTEGER)
RETURNING INTEGER;
DEFINE res INTEGER;
IF (val1 = val2) THEN
LET res = 0;
ELSE
LET res = 1;
END IF;
RETURN res;
END FUNCTION;
 4、SPL中的流程控制
     1)分支语句if...then...else...end if
     参考实例:
IF ( condition ) THEN
   statements
ELIF ( condition ) THEN
   statements
   …
ELSE
   statements
END IF;
     2)分支语句case
     参考实例:
CASE ( condition )
   WHEN <value1> THEN
      statements
   WHEN <value2> THEN
      statements
      …
    ELSE
      statements
END CASE;
     3)循环语句for
     参考语法如下:
FOR 变量 IN ( 范围或值 )
     或者使用如下语法:
FOR 变量=范围
     举例如下:
FOR count = 2 TO 30
FOR count = 2 TO 30 STEP 2
FOR count IN ( 2, 5, 7, 9)
FOR count IN ( 2 to 8 STEP 2, 12 to 19, 22)
FOR name IN ("AMY", "MAX",
(SELECT name FROM customer WHERE customer_num = 100) )
     4)循环语句while
     参考语法如下所示:
WHILE (条件表达式)
   执行的语句
END WHILE;
      while中的条件表达式的举例如下:
WHILE (count < 20)
WHILE (status matches "A*")
WHILE (EXISTS (SELECT name FROM customer WHERE cus_num=100))
WHILE (status IN ("A", "I", "D"))
      5)循环语句foreach
      i)被用来取多行数据;
      ii)它打开了一个游标;
      iii)游标用来取得当前的行,以便进行行的更新或删除操作。
      参考实例如下:
FOREACH SELECT salary INTO ind_sal
FROM customer
WHERE location = “UK"
sum_sal += ind_sal;
END FOREACH;
RETRUN sum_sal;
       6)continue或exit语句
       都可以被使用在for、foreach和while循环语句中。
       参考实例如下:
FOR i = 1 TO 5
   LET j = i;
   WHILE (j > 0)
      LET id = foo(j);
      IF (id = 5) THEN
         LET j = j – 1;
         CONTINUE WHILE; -- 不执行后续的操作,继续回到while循环接着执行
      END IF;
      LET sum = sum + 5;
      LET j = j – 1;
      IF (sum > 500) THEN
         EXIT FOR; -- 退出for循环
      END IF;
   END WHILE;
END FOR;
RETURN sum;
5、异常处理
      1)ON EXCEPTION语句
      ON EXCEPTION语句语句提供了异常的捕获和处理机制。在IN中指定要捕获的错误,并指定当异常发生时需要执行的动作。在一个语句块中允许有多个ON EXCEPTION语句。
      ON EXCEPTION语句必须在DEFINE语句之后,并在在任何可执行的语句块之前。并且它在内嵌的语句块中也是有效的。它使用SET语句来接收SQL、ISAM错误码和错误信息。
      参考实例如下所示:
CREATE PROCEDURE ex_test()
   DEFINE sql_err INTEGER;
   DEFINE isam_err INTEGER;
   DEFINE err_txt CHAR(200);
   ON EXCEPTION IN (-206) SET sql_err, isam_err, err_txt
      CREATE TABLE tab1 ( col1 INT, col2 INT);
      INSERT INTO tab1 VALUES (1, 2);
      INSERT INTO tab1 VALUES (2, 3);
   END EXCEPTION
   INSERT INTO tab1 VALUES (1, 2); --如果tab1不存在时,跳到异常处理
   INSERT INTO tab1 VALUES (2, 3);
END PROCEDURE;
       2)WITH RESUME语句
       该语句在存储过程发生错误时恢复语句。
       如下实例展示了WITH RESUME的使用,当异常处理完毕后,继续后续的语句处理。参考语句如下:
CREATE PROCEDURE ex_test()
ON EXCEPTION IN (-206)
      CREATE TABLE tab1 (col1 INT, col2 INT);
      INSERT INTO tab1 VALUES (1, 2);
END EXCEPTION WITH RESUME;
INSERT INTO tab1 VALUES (1, 2); -- 如果tab1不存在,跳到异常处理
INSERT INTO tab1 VALUES (2, 3); -- 异常处理完成后,继续该句进行处理
INSERT INTO tab1 VALUES (3, 4);
END PROCEDURE;
       3)RAISE EXCEPTION语句
       i) 该语句用来创建错误;
       ii)它能够用来指定SQL错误、ISAM错误和错误信息;
       iii)用该语句创建的错误,能够被ON EXCEPTION捕获;
       iv)可以使用指定的错误码-746来表示自定义的错误消息。
       如下实例使用ON EXCEPTION语句指明了当发生错误时将错误码、错误信息插入到自定义的错误表my_error_table,当传入的参数小于1时,抛出自定义的-746异常,其余情况成功将数据插入到tab1表中,参考语句如下:
CREATE PROCEDURE ex_test5 (a INT)
   DEFINE sql_err INTEGER;
   DEFINE isam_err INTEGER;
   DEFINE err_txt CHAR(200);
   ON EXCEPTION IN (-746) SET sql_err, isam_err, err_txt
      INSERT INTO my_error_table values (sql_err, isam_err, err_txt);
   END EXCEPTION;
   IF (a < 1) THEN
      RAISE EXCEPTION -746, 0, "插入值必须大于0";
   END IF;
   INSERT INTO tab1 VALUES (1, a);
END PROCEDURE;
6、执行SPL函数或存储过程
        可使用EXECUTE PROCEDURE语句来执行SPL存储过程,使用EXECUTE FUNCTION来执行SPL函数;
        参考实例1:
EXECUTE PROCEDURE foo();
        参考实例2:
CREATE FUNCTION func1() RETURNING INT
    DEFINE myvalue INT;
    CALL foo() RETURNING myvalue;
    INSERT INTO table1 VALUES (myvalue);
    RETURN myvalue;
END FUNCTION;
        参考实例3:
SELECT * FROM table2 WHERE id = get_id("amigo");
        参考实例4:
UPDATE table2 SET col2=foo() WHERE id=1;
7、删除SPL函数或存储过程
        1)使用DROP PROCEDURE来删除SPL存储过程;
        2)使用DROP FUNCTION来删除SPL函数;
        3)使用DROP ROUTINE来删除SPL存储过程或SPL函数。
        几个参考实例如下:
DROP PROCEDURE foo;
DROP PROCEDURE foo (INTEGER);
DROP SPECIFIC PROCEDURE foo_int;
DROP FUNCTION foo_ret;
DROP FUNCTION foo_ret (INTEGER);
DROP SPECIFIC FUNCTION foo_ret_int;
DROP ROUTINE foo;
DROP ROUTINE foo_ret;

informix 存储过程结构的更多相关文章

  1. sql:sql server,MySQL,PostgreSQL的表,视图,存储过程结构查询

    sql server 2005: --SQL SERVER 2005 生成代码需要知道的SQL语句 use LibrarySystem --查询当前数据库所有表和其的主键字段,字段类型,长度,是否为空 ...

  2. sql:Oracle11g 表,视图,存储过程结构查询

    -- Oracle 11 G --20160921 涂聚文再次修改 --Geovin Du --GetTables SELECT owner, object_name, created FROM al ...

  3. sql:MySQL 6.7 表,视图,存储过程结构查询

    #数据库MySQL 6.7 use sakila; #查询表名 show tables; # SELECT TABLE_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA. ...

  4. postgresql PL/pgSQL—存储过程结构和变量声明

    ref: https://www.postgresql.org/docs/9.6/static/plpgsql-structure.html 一. 函数结构 CREATE FUNCTION somef ...

  5. Oracle SQL存储过程结构、异常处理示例

    -- 存储过程结结构. -- EXCeption不是存储过程必须部分,可以用作本存储过程的异常处理,但如果没有异常处理,出了异常将会终止程序 CREATE PROCEDURE procedure_na ...

  6. informix存储过程笔记

    一.存储过程概述 存储过程是一个用户定义的函数,由存储过程语句(SPL) 和一组SQL语句组成,以可以执行代码形式存储在数据库中,和表.视图.索引等一样,是数据库的一种对象. 存储过程语言SPL(St ...

  7. Informix存储过程

    一.存储过程概述 存储过程是一个用户定义的函数,由存储过程语句(SPL) 和一组SQL语句组成,以可以执行代码形式存储在数据库中,和表.视图.索引等一样,是数据库的一种对象. 存储过程语言SPL(St ...

  8. 转:ORACLE存储过程笔记1----基本语法(以及与informix的比较)

    一.基本语法(以及与informix的比较)   create [or replace] procedure procedure_name (varible {IN|OUT|IN OUT} type) ...

  9. Sql Server系列:存储过程

    1 存储过程简介 存储过程是使用T-SQL代码编写的代码段.在存储过程中,可以声明变量.执行条件判断语句等其他编程功能.在MS SQL Server 2012中存储过程主要分三类:系统存储过程.自定义 ...

随机推荐

  1. Servlet入门和ServletConfig、ServletContext

    Servlet是一门用于开发动态web资源的技术. 若想开发一个动态web资源,需要完成以下2个步骤: 1)编写一个Java类,实现servlet接口: 2)把开发好的Java类部署到web服务器中. ...

  2. 持续集成环境(Hudson)搭建

    持续集成环境(Hudson)搭建 这是在公司写的,公司要求用英文,我也没时间翻译了.还请见谅! Hudson是个非常强大持续集成工具,配合svn,maven,sonar,redmine工具就更加完美了 ...

  3. 关于模型的合法性,Entity.IsValid()合理吗?

    关于模型的合法性,Entity.IsValid()合理吗? 背景 见过很多框架(包括我自己的)都会在实体的定义中包含一个IsValid()方法,用来判断实体的合法性,是否应该这样设计呢?本文就这个问题 ...

  4. poj1483 It's not a Bug, It's a Feature!

    It's not a Bug, It's a Feature! Time Limit: 5000MS   Memory Limit: 30000K Total Submissions: 1231   ...

  5. hdu1198--并查集

    Problem Description Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is ...

  6. Android ListView多布局讲解

    Listview优化是一个老生常谈的事情了,其优化的方面也有很多种,例如,布局重用.在getView()中减少逻辑计算.减少在页面滑动的时候加在图片,而是在页面停止滚动的时候再加在图片.而今天要介绍的 ...

  7. 使用unity创建塔防游戏(原译)(part1)

    塔防游戏非常地受欢迎,木有什么能比看着自己的防御毁灭邪恶的入侵者更爽的事了. 在这个包含两部分的教程中,你将使用Unity创建一个塔防游戏. 你将会学到如何: 创建一波一波的敌人 使敌人随着路标移动 ...

  8. C语言之二维数组

    二维数组 还是一个数组,只不过数组中得每一个元素又是一个数组 1). 声明语法 类型 数组名[行][列]; 例:  int nums[2][3];//2行3列的二维数组,保存的数据类型是int类型 c ...

  9. Putty的注册表设置

    Putty是一款非常好用的远程管理Linux系统的工具,其主要具有以下几个优点:  完全免费;  在Windows 9x/NT/2000下运行的都非常好;  全面支持SSH1和SSH2:  绿色软件, ...

  10. cache数据库学习周结

    学习cache数据库只有两周,下面说一下对这一数据库的理解吧.不一定对 cache数据库最大的特点是global: global就像全区变量一样,是一个广义的全局变量.数据库表中的一些重要的字段名以字 ...