zoukankan      html  css  js  c++  java
  • SQL/存储过程和函数

      存储过程和函数

    #存储过程和函数
    /*
    存储过程和函数:类似于java中的方法
    好处:
    1、提高代码的重用性
    2、简化操作
    
    */
    
    
    
    ###存储过程
    /*
    含义:一组预先编译好的SQL语句的集合,理解成批处理语句
    好处:
    1、提高代码的重用性
    2、简化了操作
    3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
    
    */
    
    #创建语法
    
    /*
    
    create procedure 存储过程名(参数列表)
    begin
        存储过程体(一组合法的SQL语句)
    end
    
    注意:
    1、参数列表包含三部分:
    
    参数模式  参数名 参数类型
    in stuname varchar(20)
    
    参数模式:
    in  :该参数可以作为输入,也就是该参数需要调用方法传入值
    out :该参数可以作为输出,也就是该参数可以作为返回值
    inout :该参数既可以作为输入也可以作为输出,也就是该参数既需要传入值,又可以返回值
    
    2、如果存储过程体仅仅只有一行,begin、end 可以省略
    存储过程体中的每条SQL语句的结尾要求必须加分号
    存储过程的结尾可以使用 delimiter 重新设置结束标记
    语法:
    delimiter 结束标记
    如:
    delimiter $
    
    */
    
    
    #二、调用语法
    
    CALL 存储过程名(实参列表);
    
    #1、空参列表
    #插入到admin表中五条记录
    
    SELECT * FROM admin;
    
    #命令行提示符下:
    DELIMITER $
    CREATE OR REPLACE PROCEDURE myp1()
    BEGIN
        INSERT INTO admin(username,`password`) VALUES('john','0000'),('jack','0000'),('rose','0000'),('tom','0000'),('lily','0000');
    END $         #结束符
    
    CALL myp1()$  #结束符
    
    SELECT * FROM admin $ #结束符
    
    #查询编辑器下
    DELIMITER $
    CREATE OR REPLACE PROCEDURE myp1()
    BEGIN
        INSERT INTO admin(username,`password`) VALUES('john','0000'),('jack','0000'),('rose','0000'),('tom','0000'),('lily','0000');
    END $    #结束符
    
    CALL myp1();
    
    SELECT * FROM admin;
    
    #delete from admin;     #自增长在断点处
    #truncate table admin;  #自增长从1开始
    
    #2、带in模式参数的存储过程
    
    #创建存储过程实现 根据女神名查询对应的男神信息
    
    DELIMITER $
    CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
    BEGIN
        SELECT bo.*
        FROM boys bo
        RIGHT JOIN beauty b 
        ON bo.id = b.boyfriend_id   #外键
        WHERE b.name = beautyName;
    END $
    
    #select * from beauty;
    CALL myp2('热巴');
    
    #创建存储过程实现,用户是否登录成功
    
    DELIMITER $
    CREATE PROCEDURE myp3(IN usenanme VARCHAR(20), IN PASSWORD VARCHAR(20))
    BEGIN
        DECLARE result INT DEFAULT 0; #声明并初始化变量
        
        SELECT COUNT(*) INTO result   #给变量赋值
        FROM admin
        WHERE admin.`username` = username
        AND admin.`password` = PASSWORD;
        
        SELECT IF(result>0,'成功','失败'); #使用变量
    END $
    
    #call myp3('张飞','8888');  #失败
    CALL myp3('john','0000');   #成功
    
    
    #3、创建带out模式的存储过程
    
    #根据女神名,返回对应的男神名
    DELIMITER $
    CREATE PROCEDURE myp4(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
    BEGIN
        SELECT bo.boyName INTO boyName
        FROM boys bo
        RIGHT JOIN beauty b 
        ON bo.id = b.boyfriend_id
        WHERE b.name = beautyName;                                                                          
    END $
    
    #SET @boyName:= '';
    CALL myp4('热巴',@boyName);  # @boyName
    SELECT @boyName;
    
    #根据女神名,返回对应的男神名和男神魅力值
    DELIMITER $
    CREATE OR REPLACE PROCEDURE myp5(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT userCP INT)
    BEGIN
        SELECT bo.boyName, bo.userCP INTO boyName, userCP  # INTO boyName, userCP 
        FROM boys bo
        RIGHT JOIN beauty b
        ON b.boyfriend_id = bo.id
        WHERE b.name = beautyName;
    END $
    
    CALL myp5('热巴',@boyName,@userCP);
    SELECT @boyName,@userCP;
    
    #4、创建带inout模式参数的存储过程
    #命令提示符下
    #传入a和b两个值,最终a和b都翻倍并返回
    
    DELIMITER $
    CREATE PROCEDURE myp6(INOUT a INT, INOUT b INT)
    BEGIN
        SET a = a*2;
        SET b = b*2;
    END $
    
    #调用
    SET @m = 10 $
    SET @n = 20 $
    CALL myp6(@m,@n) $
    
    SELECT @m, @n $
    
    #创建存储过程实现传入用户名和密码,插入到admin表中
    
    DELIMITER $
    CREATE PROCEDURE test_pro1(IN username VARCHAR(20), IN `password` VARCHAR(20))
    BEGIN
        INSERT INTO admin(admin.`username`,admin.`password`) VALUES(username,`password`);
    END $
    
    CALL test_pro1('admin','0000');
    
    
    #创建存储过程或函数实现传入女生编号,返回女神名称和女神电话
    DELIMITER $
    CREATE PROCEDURE test_pro2(IN id INT,OUT NAME VARCHAR(20),OUT phone VARCHAR(20))
    BEGIN
        SELECT beauty.`name`,beauty.`phone` INTO `name`,phone
        FROM beauty
        WHERE beauty.id = id;
    END $
    
    CALL test_pro2(1,@n,@p);
    SELECT @n,@p;
    
    
    #创建存储过程或函数实现传入两个女生生日,返回大小
    DELIMITER $
    CREATE PROCEDURE test_pro3(IN birth1 DATETIME, IN birth2 DATETIME,OUT result INT)
    BEGIN
        SELECT DATEDIFF(birth1,birth2) INTO result;
    END $
    
    CALL test_pro3('1998-1-1',NOW(),@result);
    SELECT @result;
    
    #创建存储过程或函数实现传入一个日期,格式化成XX年XX月XX日并返回
    DELIMITER $
    CREATE PROCEDURE test_pro4(IN mydate DATETIME , OUT strDate VARCHAR(50))
    BEGIN
        SELECT DATE_FORMAT(mydate, '%y年%m月%d日') INTO strDate;
    END $
    CALL test_pro4(NOW(),@date);
    SELECT @date;
    
    #创建存储过程或函数实现传入女神名称,返回:女神 and 男神 格式的字符串
    #如 传入: 小昭  返回:小昭 and 张无忌
    DELIMITER $
    CREATE PROCEDURE test_pro5(IN beautyName VARCHAR(20),OUT str VARCHAR(50))
    BEGIN
        SELECT CONCAT(beautyName,' AND ',IFNULL(bo.boyName,'null')) INTO str # ifnull
        FROM beauty b
        LEFT JOIN boys bo
        ON b.boyfriend_id = bo.id
        WHERE b.name = beautyName;
    END $
    CALL test_pro5('热巴',@str);
    CALL test_pro5('柳岩',@str);
    SELECT @str;
    
    #创建存储过程或函数,根据传入的条目数和起始索引,查询beauty表的记录
    DELIMITER $
    CREATE PROCEDURE test_pro6(IN startIndex INT,IN size INT )
    BEGIN
        SELECT *
        FROM beauty
        LIMIT startIndex,size;  #limit 
    END $
    CALL test_pro6(0,3); #limit 索引从 0 开始
    
    #二、存储过程的删除
    /*
    语法:
    drop procedure 存储过程名  #一次只能删除一个
    
    */
    DROP PROCEDURE test_pro1;
    DROP PROCEDURE test_pro2;
    
    #三、查看存储过程的信息   #没有修改存储过程
    SHOW CREATE PROCEDURE myp1;
    
    
    ###函数
    /*
    含义:一组预先编译好的SQL语句的集合,理解成批处理语句
    好处:
    1、提高代码的重用性
    2、简化了操作
    3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率
    
    与存储过程的区别:
    存储过程(适合增删改):可以有0个返回,也可以有多个返回,适合做批量的插入、批量更新
    函数:有且仅有一个返回,适合做处理数据后返回一个结果
    
    */
    
    #一、创建语法
    CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型 
    BEGIN
        函数体
    END
    
    /*
    注意:
    1、参数列表 包含两部分: 参数名 参数类型
    
    2、函数体:肯定会有 return 语句,如果没有会报错
    如果return 语句没有放在函数体的最后也不报错,但不建议
    
    return 值;
    3、函数体中只有一句话,则可以省略begin end
    4、使用delimiter语句设置结束标记
    */
    
    #二、调用语法
    SELECT 函数名(参数列表)
    
    #1、无参有返回
    #返回公司的员工个数
    DELIMITER $
    CREATE FUNCTION myf1() RETURNS INT   # returns
    BEGIN
        DECLARE c INT DEFAULT 0; #定义一个变量
        SELECT COUNT(*) INTO c FROM employees;    
        RETURN c;    
    END $
    
    SELECT myf1();
    
    #有参有返回
    #根据员工名返回它的工资
    DELIMITER $
    CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
    BEGIN
        SET @sal = 0; #定义用户变量
        SELECT salary INTO @sal FROM employees WHERE last_name = empName;
        RETURN @sal;
    END $
    
    SELECT myf2('Kochhar');
    #根据部门名,返回该部门的平均工资
    DELIMITER $
    CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
    BEGIN
        DECLARE sal DOUBLE;
        SELECT AVG(salary) INTO sal
        FROM employees e
        JOIN departments d 
        ON e.department_id = d.department_id
        WHERE d.department_name = deptName;
        RETURN sal;
    END $
    
    SELECT myf3('IT');
    
    #三、查看函数
    SHOW CREATE FUNCTION myf3;  # create
    
    #四、删除函数
    DROP FUNCTION myf3;
    
    #创建函数,实现传入两个float,返回二者之和
    DELIMITER $
    CREATE FUNCTION test_fun1(num1 FLOAT, num2 FLOAT) RETURNS FLOAT
    BEGIN 
        DECLARE SUM FLOAT DEFAULT 0;
        SET SUM = num1 + num2;
        RETURN SUM;
    END $
    
    SELECT test_fun1(1,2);
    View Code
  • 相关阅读:
    AtCoder Beginner Contest 167
    AtCoder Beginner Contest 166
    AtCoder Beginner Contest 165
    AtCoder Beginner Contest 164
    AtCoder Beginner Contest 163
    AtCoder Beginner Contest 162
    AtCoder Beginner Contest 161
    AtCoder Beginner Contest 160
    AtCoder Beginner Contest 159
    自定义Mybatis自动生成代码规则
  • 原文地址:https://www.cnblogs.com/GoldenEllipsis/p/15192388.html
Copyright © 2011-2022 走看看