zoukankan      html  css  js  c++  java
  • mysql 开发基础系列17 存储过程和函数(上)

    一. 概述 

     存储过程和函数是事先经过编译并存储在数据库中的一段sql语句集合,可以简化应用开发人员的很多工作,减少数据在数据库与应用服务器之间的传输,提高数据处理效率是有好处的。存储过程和函数的区别在于函数必须有返回值,存储过程的参数可以使用in,out ,inout类型,而函数参数只能是in类型。 创建需要create routine 权限, 修改删除需要alter routine权限,执行需要execute权限。

      1.1 创建存储过程,调用,删除

    -- 创建
    DELIMITER $$
    CREATE PROCEDURE proc_city(IN city_id INT ,OUT num INT)
    READS SQL DATA
    BEGIN
        --  要设置初始值,不然为null 与sqlserver一样
        SET num=0;
        SELECT * FROM city WHERE city.city_id=city_id;
        SET num=num+1;
    END $$
    DELIMITER ;
    
     --  调用
    CALL proc_city (2,@num); SELECT @num;

    -- 删除
    DROP  PROCEDURE proc_city

      特征值介绍:
      CREATE PROCEDURE proc_name()
        { contains sql | no sql | READS SQL DATA | modifies sql data}
      这个特征值只是提供给服务器,并没有根据这些特征值来约束过程实际使用数据的情况。 contains sql 表示子程序不包含读或写数据的语句。no sql表示子程序不包含sql 语句。 READS SQL DATA:表示子程序包含数据的语句,但不包含写数据。modifies sql data 表示子程序包含写数据。默认是contains sql。

      1.2 创建函数,调用,删除

    -- 创建
    SET GLOBAL log_bin_trust_function_creators=TRUE;
    DELIMITER $$
    CREATE FUNCTION fn_city (city_count INT)
    RETURNS INT 
    BEGIN
    DECLARE  city_count1 INT;
        --  要设置初始值,
        SET city_count1=0;
        SET  city_count1=city_count+1;
        RETURN city_count1;
    END $$
    DELIMITER ;
    
    -- 调用
    SELECT  fn_city (2);

    -- 删除
    DROP FUNCTION fn_city

      1.3 查看信息

    SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME='proc_city' OR  ROUTINE_NAME='fn_city'

     

        1.4 变量的使用

    DELIMITER $$
    CREATE PROCEDURE proc_demo_declare()
    READS SQL DATA
    BEGIN
        -- 定义 
        DECLARE i INT ;
        -- 赋值
        SET i=10;
        SELECT i;
        -- 第二种赋值
        SELECT COUNT(1) INTO i  FROM city;
        SELECT i;
    END $$
    DELIMITER ;
    
    call proc_demo_declare;

              

      1.5 定义Handler遇到问题的处理步骤

    --  语法
    DECLARE
    {EXIT | CONTINUE}
    HANDLER FOR
    {error-number | SQLSTATE error-STRING | CONDITION}
    SQL statement

      (1) 处理类型{EXIT | CONTINUE} continue: 当遇到执行错误时,跳过继续下面的语句。exit: 当遇到执行错误时,停止语句
      (2) 触发条件 (SQLSTATE,MYSQL ERROR,CONDITION)MYSQL错误代码。ANSI-standard SQLSTATE code。命名条件。可使用系统内置的SQLEXCEPTION,SQLWARNING和NOT FOUND。
      (3)错误触发的操作。

    --   以continue为例
    DELIMITER $$
    CREATE PROCEDURE proc_demo_handler_continue()
    BEGIN
        -- 定义条件 continue : 当遇到执行错误时,跳过继续下面的语句
        DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;    
        
        -- 这条可以插入
        INSERT INTO  city(country_id,cityname,Citycode) VALUES(2,'中国','cn4');
        SET @x=1;
        
        -- 这条不能插入,外键约束fk_city_country
        INSERT INTO  city(country_id,cityname,Citycode) VALUES(8,'中国','cn5');
        SET @x=2;
        
        -- 这条可以插入
        INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn6');
        SET @x=3;
    END $$
    DELIMITER ;
    -- 调用 
    CALL proc_demo_handler_continue; SELECT @x,@x2;

      使用了continue: 当遇到执行错误时,跳过继续下面的语句,三条语句,只插入成功二条成功

      

    --  以exit为例
    DELIMITER $$
    CREATE PROCEDURE proc_demo_handler_exit()
    BEGIN
        -- 定义条件  : 当遇到执行错误时,停止语句  
        DECLARE EXIT HANDLER FOR SQLSTATE '23000' SET @x2 = 1;    
        
        -- 这条可以插入
        INSERT INTO  city(country_id,cityname,Citycode) VALUES(2,'中国','cn4');
        SET @x=1;
        
        -- 这条不能插入,外键约束fk_city_country
        INSERT INTO  city(country_id,cityname,Citycode) VALUES(8,'中国','cn5');
        SET @x=2;
        --  这条不可以插入
        INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn6');
        SET @x=3;
    END $$
    DELIMITER ;
    -- 调用
    CALL proc_demo_handler_exit;SELECT @x,@x2;

      使用了exit: 当遇到执行错误时,停止语句, 三条语句,只插入成功第一条

  • 相关阅读:
    使用PHP获取用户客户端真实IP的解决方案
    PHP中使用mkdir创建多级目录的方法
    javascript中将字符串转换为json格式的三种方法
    Codeigniter处理用户登录验证后URL跳转
    PHP正则表达式匹配URL中的域名
    开源项目列表
    PG JDBC COPY感谢原作者
    if中return的用法
    读数据库查询的 ResultSet时java.sql.SQLException: 流已被关闭
    一篇讲JAVA JDBC的好文章
  • 原文地址:https://www.cnblogs.com/MrHSR/p/9289853.html
Copyright © 2011-2022 走看看