• 数据库中的存储过程、游标、触发器与常用的内置函数


    目录

    1 存储过程(本节使用MySQL描述)

    1.1 什么是存储过程

    (1)概念

    (2)作用

    1.2 存储过程的定义

    (1)语法:

    (2)示例

     2 游标(本节使用Oracle描述)

    2.1 什么是游标

    2.2 使用语法

    2.3 示例

    3 触发器

    3.1 什么是触发器

    (1)触发器(trigger)

    (2)触发器的定义语法:

    (3)MySQL中可以创建 6 种触发器

    3.2 示例(本节使用MySQL描述)

    (1)after insert 触发器,在插入数据之后获得@id变量以显示最新的自增长ID

    (2)after delete 触发器,把被删除的行数据保存在一个存档表中

    (3)before update 触发器,确保更新后name字段的值总是大写的

    4 常用的数据库内置函数

     4.1 文本函数

    4.2 日期/时间函数


    1 存储过程(本节使用MySQL描述)

    1.1 什么是存储过程

    (1)概念

    存储过程(Stored Procedure)是是数据库中的一个重要对象,是一组为了完成特定功能 的SQL 语句的集合,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过 指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

    (2)作用

    存储过程吧处理封在容易使用的单元中,简化复杂的操作; 确保大家都使用到统一的代码; 独立授权,简化管理,增加安全性; 编译执行,提高性能。

    1.2 存储过程的定义

    (1)语法:

    1. #创建存储过程
    2. delimeter //
    3. create procedure 存储过程名(
    4. in 参数名 类型,
    5. out 参数名 类型,
    6. ...
    7. )
    8. begin
    9. 执行的一组语句
    10. end //
    11. delimeter ;
    12. #删除存储过程
    13. drop procedure 存储过程名
    14. #调用
    15. call 存储过程名(参数列表)

    (2)示例

    1. #示例1 简单存储过程
    2. #删除存储过程
    3. DROP PROCEDURE album_avg_pricing;
    4. #创建存储过程
    5. DELIMITER // #delmiter 切换 // 作为分隔符
    6. CREATE PROCEDURE album_avg_pricing()
    7. BEGIN
    8. SELECT AVG(price) avg_price FROM album;
    9. END //
    10. DELIMITER ; #delmiter 还原 ; 作为分隔符
    11. #调用存储过程
    12. CALL album_avg_pricing();
    13. #示例2 带输入参数
    14. #删除
    15. DROP PROCEDURE album_stocking;
    16. #创建
    17. DELIMITER //
    18. CREATE PROCEDURE album_stocking(
    19. albumId INT,
    20. amount INT
    21. )
    22. BEGIN
    23. UPDATE album SET stock=stock+amount WHERE id=albumId;
    24. END //
    25. DELIMITER ;
    26. #调用
    27. CALL album_stocking(1,15);
    28. #示例3 输出参数
    29. #删除
    30. DROP PROCEDURE album_pricing;
    31. #创建
    32. DELIMITER //
    33. CREATE PROCEDURE album_pricing(
    34. OUT min_price DECIMAL(8,2),
    35. OUT max_price DECIMAL(8,2),
    36. OUT avg_price DECIMAL(8,2)
    37. )
    38. BEGIN
    39. SELECT MIN(price) INTO min_price FROM album;
    40. SELECT MAX(price) INTO max_price FROM album;
    41. SELECT AVG(price) INTO avg_price FROM album;
    42. END //
    43. DELIMITER ;
    44. #调用
    45. CALL album_pricing(@min, @max, @avg);
    46. SELECT @min,@max,@avg;
    47. #示例4 混合参数
    48. #删除
    49. DROP PROCEDURE order_total_qty;
    50. #创建
    51. DELIMITER //
    52. CREATE PROCEDURE order_total_qty(
    53. IN order_id INT,
    54. OUT total_qty INT
    55. )
    56. BEGIN
    57. SELECT SUM(quantity) INTO total_qty FROM orderdetail WHERE
    58. orderId=order_id;
    59. END //
    60. DELIMITER ;
    61. #调用
    62. CALL order_total_qty(1, @qty);
    63. SELECT @qty;

     2 游标(本节使用Oracle描述)

    2.1 什么是游标

    游标是一组查询结果集中的行级指针。在查询结果集中,通过游标可以单独针对一行数据执 行操作,也可以前进或后对一行或多行。

    2.2 使用语法

    1. declare
    2. cursor 游标 is select语句;
    3. begin
    4. open 游标;
    5. loop
    6. fetch cur into item;
    7. if cur%notfound then
    8. exit;
    9. end if;
    10. ......
    11. end loop;
    12. close 游标;
    13. end;

    2.3 示例

    游标的创建、打开、循环获取和关闭:

    1. declare
    2. cursor cur is select * from movie;
    3. item movie%rowtype;
    4. begin
    5. open cur;
    6. loop
    7. fetch cur into item;
    8. if cur%notfound then
    9. exit;
    10. end if;
    11. dbms_output.put_line(item.title);
    12. end loop;
    13. close cur;
    14. end;

    游标参数与循环游标:

    1. declare
    2. cursor cur(vid number) is select m.*, c.name cname from movie m
    3. inner join category c on m.categoryid=c.id
    4. where categoryid=vid;
    5. begin
    6. for record in cur(2) loop
    7. dbms_output.put_line(to_char(record.cname) || ',' ||
    8. record.title);
    9. end loop;
    10. end;

    3 触发器

    3.1 什么是触发器

    (1)触发器(trigger)

    是一种数据库对象,用于监控某些语句,在满足定义条件时触发, 并执行触发器中定义的一组语句。

    (2)触发器的定义语法:

    1. CREATE TRIGGER trigger_name
    2. trigger_time
    3. trigger_event ON table_name
    4. FOR EACH ROW trigger_statement

    trigger_name: 触发器的名称

    tirgger_time: 触发时机,为BEFORE或者AFTER

    trigger_event: 触发事件,为INSERT、DELETE或者UPDATE

    table_name: 表示建立触发器的表明,就是在哪张表上建立触发器

    trigger_stmt: 触发器的程序体,可以是一条SQL语句或者是用BEGIN和END包含的多条 语句

    (3)MySQL中可以创建 6 种触发器

    1. #(1)BEFORE INSERT
    2. #(2)BEFORE DELETE
    3. #(3)BEFORE UPDATE
    4. #(4)AFTER INSERT
    5. #(5)AFTER DELETE
    6. #(6)AFTER UPDATE

    3.2 示例(本节使用MySQL描述)

    (1)after insert 触发器,在插入数据之后获得@id变量以显示最新的自增长ID

    1. #删除触发器
    2. DROP TRIGGER new_genre;
    3. #添加触发器
    4. CREATE TRIGGER new_genre
    5. AFTER INSERT ON genre
    6. FOR EACH ROW
    7. SELECT new.id INTO @id;
    8. #引发触发器
    9. INSERT INTO genre VALUES(0,'123','123');
    10. SELECT @id;

    注意:在insert触发器内,可以引用一个名为new的虚拟表,访问被插入的行。

    (2)after delete 触发器,把被删除的行数据保存在一个存档表中

    1. CREATE TABLE genre_bak( id INT, NAME VARCHAR(120), description TEXT);
    2. #删除触发器
    3. DROP TRIGGER delete_genre;
    4. #添加触发器
    5. CREATE TRIGGER delete_genre
    6. AFTER DELETE ON genre
    7. FOR EACH ROW
    8. INSERT INTO genre_bak(id, NAME, description)
    9. VALUES(old.id, old.name, old.description);
    10. #引发触发器
    11. DELETE FROM genre WHERE id=6;

    注意:在delete触发器内,可以引用一个名为old的虚拟表,访问被删除的行

    (3)before update 触发器,确保更新后name字段的值总是大写的

    1. #删除触发器
    2. DROP TRIGGER update_genre;
    3. #添加触发器
    4. CREATE TRIGGER update_genre
    5. BEFORE UPDATE ON genre
    6. FOR EACH ROW
    7. SET new.name=UPPER(new.name);
    8. #引发触发器
    9. UPDATE genre SET NAME='abc' WHERE id=8;

    注意:在update触发器内,可以引用一个名为old虚拟表,访问更新前的行;new一个名为的虚拟表,访问新更新的值

    4 常用的数据库内置函数

    MySQL中预定义了很多数据处理函数:https://www.cnblogs.com/xuyulin/p/5468102.html

     4.1 文本函数

    left(str,len)/right(str,len)返回左边的字符串
    length(str)返回字符串长度
    lower(str)/upper(str)转换为小写/大写
    substring(str,pos,len)返回字符串str的位置pos起len个字符

     

    4.2 日期/时间函数

    (1)now() 

      返回当前日期和时间

    (2)year(date) / month(date) / day(date) / hour(data) / minute(date) / second(date) 

      返回日期date的年 / 月 / 日 / 时 / 分 / 秒

    (3)DayOfWeek()

      返回日期date对应的星期几(1代表星期日)

    (4)AddDate(date,interval expr type) / SubDate(date,interval expr type)

    在date的基础上添加expr时间间隔,如:SELECT ADDDATE(NOW(), INTERVAL 1 DAY);

    在date的基础上减去expr时间间隔 ,如:SELECT SUBDATE(NOW(), INTERVAL 1 DAY);

    [type值 含义 期望的expr格式]:

    1. second 秒 seconds
    2. minute 分钟 minutes
    3. hour 时间 hours
    4. day 天 days
    5. month 月 months
    6. year 年 years
    7. minute_second 分钟和秒 "minutes:seconds"
    8. hour_minute 小时和分钟 "hours:minutes"
    9. day_hour 天和小时 "days hours"
    10. year_month 年和月 "years‐months"
    11. hour_second 小时, 分钟, "hours:minutes:seconds"
    12. day_minute 天, 小时, 分钟 "days hours:minutes"
    13. day_second 天, 小时, 分钟, 秒 "days

    (5)DateDiff(date1, date2)

       计算两个日期之差,例如: 

    SELECT DATEDIFF(NOW(), '2019‐2‐28')

  • 相关阅读:
    灿芯股份将上会:计划募资6亿元,董事长、总经理均为外籍
    软件设计模式系列之六——单例模式
    [管理与领导-73]:IT基层管理者 - 辅助技能 - 4- 职业发展规划 - 如何持续提升自我
    Bika LIMS 开源LIMS集——实验室检验流程概述及主页、面板
    【计算机网络实验】单区域OSPF配置实验
    硬件工程师经常犯的几个典型错误
    如何编写基本的Java程序
    牛客网_HJ1_字符串最后一个单词的长度
    项目管理标杆和先驱——华为管理体系(PMP),一文看懂!
    唯有自身强大才能呼风唤雨—Intel要携CXL一统互联江湖了吗?
  • 原文地址:https://blog.csdn.net/qq_55917018/article/details/127907591