栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

数据库学习笔记(SQL04)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据库学习笔记(SQL04)

函数和过程

声明和调用SQL函数和过程
--给定一个系的名字,返回该系的教师数目
CREATE FUNCTION dept_count (dept_name varchar(20))
  RETURNS integer
    BEGIN
    DECLARE d_count integer;
        select count (* ) INTO d_count
        from instructor
        where instructor.dept_name = dept_name
    RETURN d_count;
    END
    
------

--调用
select dept_name, budget
from department
where dept_count (dept_name ) > 12
  • 表函数:返回的结果是关系
--以表为值的函数可以被看作带参数的视图,它通过允许参数把视图的概念更加一般化
CREATE FUNCTION instructors_of (dept_name char(20))
		RETURNS TABLE (
      ID  varchar(5),
      name varchar(20),
      dept_name varchar(20),
      salary  numeric(8,2))
RETURN TABLE
  (select ID, name, dept_name, salary
   from  instructor
   where instructor.dept_name = instructors_of.dept_name)
--??使用函数的参数时需要加上函数名作为前缀:instructor_of.dept_name

------

select *
from table (instructors_of ('Music'))
  • 过程
--IN和OUT分别表示待赋值的参数和为返回结果而在过程中设置值的参数
CREATE PROCEDURE dept_count_proc (IN dept_name varchar(20),OUT d_count integer)
  BEGIN
	  select count(*) INTO d_count
    from instructor
    where instructor.dept_name = dept_count_proc.dept_name
  END

------

--可以从一个SQL过程或者嵌入式SQL里使用call语句调用过程
DECLARE d_count integer;
CALL dept_count_proc('Physics', d_count);

支持过程和函数的语言构造
  • 变量用过declare语句进行声明,可以是任意的合法SQL类型。使用set语句进行赋值
  • 一个复合语句有begin…end的形式,begin和end之间会包含复杂的SQL语句
  • 可以在复合语句中声明局部变量
  • begin atomic…end的符合语句可以确保其包含的所有语句作为单一事务
DECLARE n integer DEFAULT 0;
		WHILE n < 10 do
		    SET n = n + 1
		END WHILE
    
		REPEAT
        SET n = n  – 1
		UNTIL n = 0
		END REPEAT

------


--for循环,对查询到的所有结果重复执行
DECLARE n integer DEFAULT 0;
FOR r AS
  select budget 
  from department
  where building='Watson'
DO
  SET n = n + r.budget
  END FOR
--程序每次获得查询结果的一行并存入for循环变量(r)中
--leave语句可以跳出循环,iterate表示跳过剩余语句从循环的开始进入下一个元组(break和continue?)

-------

--if-then-else
IF 布尔表达式
  THEN 复合语句
ELSEIF 布尔表达式
  THEN 复合语句
ELSE 复合语句
END IF

-----

--SQL支持case语句

-----

--SQL支持发信号通知异常条件,声明句柄来处理异常
DECLARE out_of_classroom_seats CONDITION
DECLARE EXIT HANDLER FOR out_of_classroom_seats
BEGIN
  …
END

触发器
  • 之名什么条件下执行触发器。分为引起触发器被检测的事件和一个触发器执行必须满足的条件
  • 指明触发器执行的动作
  • 例如教材的例子,time_slot表记录了课程可能的每一个时段,section表记录了课程开设的时间和地点信息,其中开课时段time_slot_id和time_slot表中的的time_slot_id保持一致性,但是又无法用外键来约束。这时候可以用trigger的机制
CREATE TRIGGER timeslot_check1 AFTER INSERT ON section
  REFERENCING NEW ROW AS nrow  --建立一个临时变量存储新增的数据,是一个临时表
  FOR EACH ROW   --一个SQL插入语句可以像关系中插入多个元组。此可以现实地在每个被插入的行上进行迭代
  WHEN (nrow.time_slot_id NOT IN ( --condition
    SELECt time_slot_id
    FROM time_slot))
  BEGIN
    ROLLBACK --action
  END;

-----


CREATE TRIGGER timeslot_check2 AFTER DELETe ON timeslot
  REFERENCING OLD ROW AS orow  --建立临时变量存储删掉或修改行的旧数据
  FOR EACH ROW
  WHEN (
    orow.time_slot_id NOT IN (
      SELECT time_slot_id
      FROM time_slot) AND 
    orow.time_slot_id IN (
      select time_slot_id
      FROM section))
  BEGIN
    rollback
  END;

------

CREATE TRIGGER credits_earned AFTER UPDATe OF takes ON (grade)
   REFERENCING NEW ROW AS nrow
   REFERENCING OLD ROW AS orow
   FOR EACH ROW
   WHEN nrow.grade <> 'F' AND nrow.grade IS NOT NULL
     AND (orow.grade = 'F' OR orow.grade IS NULL)
   BEGIN ATOMIC
     UPDATE student
     SET tot_cred = tot_cred + 
       (SELECT credits
        FROM course
        WHERe course.course_id = nrow.course_id)
      WHERe student.id = nrow.id
    END;

------

--可以在event之前触发
CREATE TRIGGER setnull_trigger BEFORE UPDATE OF takes
  REFERENCING NEW ROW AS nrow
  FOR EACH ROW
  WHEN (nrow.grade = '')
    BEGIN ATOMIC
      SET nrow.grade = null;
    END;

-----

--可以设置为有效或者无效
ALTER TRIGGER 名字 DISABLE
或者
DISABLE TRIGGER 名字

何时不用trigger
  • trigger时要特别小心,因为运行期间一个trigger错误会导致引发该trigger的action语句失败,而且一个trigger的动作可以引发另一个触发器,最坏情况下,会导致一个无限的触发链
  • 如果有其他替代方法最好不用trigger,可以用存储过程来实现相应的功能
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996730.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号