基于oracle数据库存储过程的创建及调用

教学大纲:

  1. PLSQL编程:Hello World、程序结构、变量、流程控制、游标.
  2. 存储过程:概念、无参存储、有参存储(输入、输出).
  3. JAVA调用存储存储过程.

1. PLSQL编程1.1. 概念和目的

什么是PL/SQL?

  1. PL/SQL(Procedure Language/SQL)
  2. PLSQL是Oracle对sql语言的过程化扩展 (类似于Basic)
  3. 指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。

1.2. 程序结构

通过Plsql Developer工具的Test Window 创建 程序模版或者通过语句在SQL Window编写

提示:PLSQL语言的大小写是不区分的

PL/SQL可以分为三个部分:声明部分、可执行部分、异常处理部分。

其中 DECLARE部分用来声明变量或游标(结果集类型变量),如果程序中无变量声明可以省略掉

1.3. Hello World

其中DBMS_OUTPUT 为oracle内置程序包,相当于Java中的System.out,而PUT_LINE()是调用的方法,相当于println()方法

在sqlplus中也可以编写运行PLSQL程序:

执行结束后并未显示输出的结果,默认情况下,输出选项是关闭状态的 我们需要开启一下 set serveroutput on

SQLPLUS中执行PLSQL程序 需要在程序最后添加一个 / 标识程序的结束

1.4. 变量

PLSQL编程中常见的变量分两大类:

  1. 普通数据类型(char,varchar2, date, number, boolean, long)
  2. 特殊变量类型(引用型变量、记录型变量)

声明变量的方式为

1.4.1. 普通变量

变量赋值的方式有两种:

  1. 直接赋值语句 := 比如: v_name := \’zhangsan\’
  2. 语句赋值,使用select …into … 赋值:(语法 select 值 into 变量)

【示例】打印人员个人信息,包括: 姓名、薪水、地址

1.4.2. 引用型变量

变量的类型和长度取决于表中字段的类型和长度

通过表名.列名%TYPE指定变量的类型和长度,例如: v_name emp.ename%TYPE;

【示例】查询emp表中7839号员工的个人信息,打印姓名和薪水

引用型变量的好处:

使用普通变量定义方式,需要知道表中列的类型,而使用引用类型,不需要考虑列的类型,使用%TYPE是非常好的编程风格,因为它使得PL/SQL更加灵活,更加适应于对数据库定义的更新。

1.4.3. 记录型变量

接受表中的一整行记录,相当于Java中的一个对象

语法: 变量名称 表名%ROWTYPE, 例如: v_emp emp%rowtype;

【示例】

查询并打印7839号员工的姓名和薪水

如果有一个表,有100个字段,那么你程序如果要使用这100字段话,如果你使用引用型变量一个个声明,会特别麻烦,记录型变量可以方便的解决这个问题

错误的使用:

1. 记录型变量只能存储一个完整的行数据

2.返回的行太多了,记录型变量也接收不了

1.5. 流程控制1.5.1. 条件分支

语法:

注意关键字:ELSIF

【示例】判断emp表中记录是否超过20条,10-20之间,或者10条以下

1.5.2. 循环

在ORACLE中有三种循环方式,这里我们不展开,只介绍其中一种:loop循环

语法:

【示例】打印数字1-10

2. 游标2.1. 什么是游标

用于临时存储一个查询返回的多行数据(结果集,类似于Java的Jdbc连接返回的ResultSet集合),通过遍历游标,可以逐行访问处理该结果集的数据。

游标的使用方式:声明—>打开—>读取—>关闭

2.2. 语法

游标声明:

CURSOR 游标名[(参数列表)] IS 查询语句;

游标的打开:

OPEN 游标名;

游标的取值:

FETCH 游标名 INTO 变量列表;

游标的关闭:

CLOSE 游标名;

2.3. 游标的属性

游标的属性返回值类型说明

其中 %NOTFOUND是在游标中找不到元素的时候返回TRUE,通常用来判断退出循环

2.4. 创建和使用

【示例】使用游标查询emp表中所有员工的姓名和工资,并将其依次打印出来。

执行结果:

2.5. 带参数的游标

【示例】使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时手动输入。

注意:%NOTFOUND属性默认值为FLASE,所以在循环中要注意判断条件的位置.如果先判断在FETCH会导致最后一条记录的值被打印两次(多循环一次默认);

3. 存储过程3.1. 概念作用

之前我们编写的PLSQL程序可以进行表的操作,判断,循环逻辑处理的工作,但无法重复调用.

可以理解之前的代码全都编写在了main方法中,是匿名程序. JAVA可以通过封装对象和方法来解决复用问题

PLSQL是将一个个PLSQL的业务处理过程存储起来进行复用,这些被存储起来的PLSQL程序称之为存储过程

存储过程作用:

1, 在开发程序中,为了一个特定的业务功能,会向数据库进行多次连接关闭(连接和关闭是很耗费资源), 需要对数据库进行多次I/O读写,性能比较低。如果把这些业务放到PLSQL中,在应用程序中只需要调用PLSQL就可以做到连接关闭一次数据库就可以实现我们的业务,可以大大提高效率.

2, ORACLE官方给的建议:能够让数据库操作的不要放在程序中。在数据库中实现基本上不会出现错误,在程序中操作可能会存在错误.(如果在数据库中操作数据,可以有一定的日志恢复等功能.)

3.2. 语法

根据参数的类型,我们将其分为3类讲解:

l 不带参数的

l 带输入参数的

l 带输入输出参数(返回值)的。

3.3. 无参存储3.3.1. 创建存储

通过Plsql Developer或者语句创建存储过程:

【示例】 通过调用存储过程打印hello world

创建存储过程:

通过工具查看创建好的存储过程:

3.3.2. 调用存储过程

1.通过PLSQL程序调用:

2.在SQLPLUS中通过EXEC命令调用:

提示:SQLPLUS中显示结果的前提是需要 set serveroutput on

注意:

第一个问题:is和as是可以互用的,用哪个都没关系的 第二个问题:过程中没有declare关键字,declare用在语句块中

3.4. 带输入参数的存储过程

【示例】查询并打印某个员工(如7839号员工)的姓名和薪水–存储过程:要求,调用的时候传入员工编号,自动控制台打印。

命令调用:

PLSQL程序调用:

执行结果:

3.5. 带输出参数的存储过程

【示例】输入员工号查询某个员工(7839号员工)信息,要求,将薪水作为返回值输出,给调用的程序使用。

PLSQL程序调用:

注意:调用的时候,参数要与定义的参数的顺序和类型一致.

3.7. JAVA程序调用存储过程

需求:如果一条语句无法实现结果集, 比如需要多表查询,或者需要复杂逻辑查询,我们可以选择调用存储查询出你的结果.

3.7.1. 分析jdk API

通过Connection对象的prepareCall方法可以调用存储过程

得出结论: 通过Connection对象调用prepareCall方法传递一个转义sql语句调用存储过程, 输入参数直接调用set方法传递.输出参数需要注册后,执行存储过程,通过get方法获取.参数列表的下标是从1开始

3.7.2. 实现代码

准备环境:

完整的学习视频,可点击:了解更多

面试官突然问我MySQL存储过程,我竟然连基础都不会!(详细)

MySQL存储过程

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升

当我们了了解存储过程是什么之后,就需要了解数据库中存在的这三种类型的数据库存储类型程序,如下:

  • 存储过程: 存储过程是最常见的存储程序,存储过程是能够接受输入和输出参数并且能够在请求时被执行的程序单元。
  • 存储函数: 存储函数和存储过程很相像,但是它的执行结果会返回一个值。最重要的是存储函数可以被用来充当标准的 SQL 语句,允许程序员有效的扩展 SQL 语言的能力。
  • 触发器: 触发器是用来响应激活或者触发数据库行为事件的存储程序。通常,触发器用来作为数据库操作语言的响应而被调用,触发器可以被用来作为数据校验和自动反向格式化。

注意: 其他的数据库提供了别的数据存储程序,包括包和类。目前MySQL不提供这种结构。

虽然目前的开发中存储程序我们使用的并不是很多,但是不一定就否认它。其实存储程序会为我们使用和管理数据库带来了很多优势:

  • 使用存储程序更加安全。
  • 存储程序提供了一种数据访问的抽象机制,它能够极大的改善你的代码在底层数据结构演化过程中的易维护性。
  • 存储程序可以降低网络拥阻,因为属于数据库服务器的内部数据,这相比在网上传输数据要快的多。
  • 存储程序可以替多种使用不同构架的外围应用实现共享的访问例程,无论这些构架是基于数据库服务器外部还是内部。
  • 以数据为中心的逻辑可以被独立的放置于存储程序中,这样可以为程序员带来更高、更为独特的数据库编程体验。
  • 在某些情况下,使用存储程序可以改善应用程序的可移植性。(在另外某些情况下,可移植性也会很差!)

我们要知道在Java语言中,我们使用数据库与Java代码结合持久化存储需要引入JDBC来完成。会想到JDBC,我们是否还能想起SQL注入问题呢?虽然使用PreparedStatement解决SQL注入问题,那就真的是绝对安全吗?不,它不是绝对安全的。

这时候分析一下数据库与Java代码的连接操作流程。在BS结构中,一般都是浏览器访问服务器的,再由服务器发送SQL语句到数据库,在数据库中对SQL语句进行编译运行,最后把结果通过服务器处理再返回浏览器。在此操作过程中,浏览器对服务器每发送一次对数据库操作的请求就会调用对应的SQL语句编译和执行,这是一件十分浪费性能的事情, 性能下降 了就说明对数据库的操作 效率低 了。

还有一种可能是,在这个过程中进行发送传输的SQL语句是对真实的库表进行操作的SQL语句,如果在发送传输的过程中被拦截了,一些不法分子会根据他所拦截的SQL语句推断出我们数据库中的库表结构,这是一个很大的 安全隐患

关于可维护性的提高,这里模拟一个场景。通常数据库在公司中是由DBA来管理的,如果管理数据库多年的DBA辞职了,此时数据库会被下一任DBA来管理。这里时候问题来了,数据库中这么多的数据和SQL语句显然对下一任管理者不太友好。就算管理多年的DBA长时间不操作查看数据库也会忘记点什么东西。所以,我们在需要引入存储程序来进行SQL语句的统一编写和编译, 为维护提供了便利 。(其实我觉得这个例子并不生动合理,但是为了大家能理解,请体谅!)

讲了很多存储程序的优势演变过程,其核心就是:需要将编译好的一段或多段SQL语句放置在数据库端的存储程序中,以便解决以上问题并方便开发者直接调用。

存储过程时数据库的一个重要的对象,可以封装SQL语句集,可以用来完成一些较复杂的业务逻辑,并且可以入参(传参)、出参(返回参数),这里与Java中封装方式十分相似。

而且创建时会预先编译后保存,开发者后续的调用都不需要再次编译。

存储过程使用的优缺点其实在1.3中的优势中说到了。这里我简单罗列一下存储过程的优点与缺点。

  • 优点:
  • 在生产环境下,可以通过直接修改存储过程的方式修改业务逻辑或bug,而不用重启服务器。
  • 执行速度快,存储过程经过编译之后会比单独一条一条编译执行要快很多。
  • 减少网络传输流量。
  • 便于开发者或DBA使用和维护。
  • 在相同数据库语法的情况下,改善了可移植性。
  • 缺点:
  • 过程化编程,复杂业务处理的维护成本高。
  • 调试不便。
  • 因为不同数据库语法不一致,不同数据库之间可移植性差。

英语好或者有能力的小伙伴可以去参考一下官方文档。如果不参考官方文档,没关系,我在下面也会详细讲述MySQL存储过程的各个知识点。

in 是定义传入参数的关键字。 out 是定义出参的关键字。 inout 是定义一个出入参数都可以的参数。如果括号内什么都不定义,就说明该存储过程时一个无参的函数。在后面会有详细的案例分析。

注意:SQL语句默认的结束符为 ; ,所以在使用以上存储过程时,会报1064的语法错误。我们可以使用 DELIMITER 关键字临时声明修改SQL语句的结束符为 // ,如下:

例如:使用存储过程来查询员工的工资(无参)

注意:如果在特殊的必要情况下,我们还可以通过 delimiter 关键字将 ; 结束符声明回来使用,在以下案例中我并没有这样将结束符声明回原来的 ; ,在此请大家注意~

为什么我在这里提供了drop(删除)呢?

是因为我们在使用的时候如果需要修改存储过程中的内容,我们需要先删除现有的存储过程后,再creat重新创建。

声明局部变量语法: declare var_name type [default var_value];

注意:局部变量的定义,在begin/end块中有效。

使用set为参数赋值

使用into接收参数

用户自定义用户变量,当前会话(连接)有效。与Java中的成员变量相似。

  • 语法: @val_name
  • 注意: 该用户变量不需要提前声明,使用即为声明。

会话变量是由系统提供的,只在当前会话(连接)中有效。

语法: @@session.val_name

这里我获取了一下所有的会话变量,大概有500条会话变量的记录。等我们深入学习MySQL后,了解了各个会话变量值的作用,可以根据需求和场景来修改会话变量值。

image-20200610112512964

全局变量由系统提供,整个MySQL服务器内有效。

语法: @@global.val_name

入参出参的语法我们在文章开头已经提过了,但是没有演示,在这里我将演示一下入参出参的使用。

语法: in|out|inout 参数名 数据类型 , …

in 定义出参; out 定义入参; inout 定义出参和入参。

出参in

使用出参in时,就是需要我们传入参数,在这里可以对参入的参数加以改变。简单来说in只负责传入参数到存储过程中,类似Java中的形参。

入参out

在使用out时,需要传入一个参数。而这个参数相当于是返回值,可以通过调用、接收来获取这个参数的内容。简单来说out只负责作返回值。

入参出参inout

inout关键字,就是把in和out合并成了一个关键字使用。被关键字修饰的参数既可以出参也可以入参。

扩展: timestampdiff(unit, exp1, exp2) 为exp2 – exp1得到的差值,而单位是unit。(常用于日期)

扩展例子: select timestampdiff(year,’2020-6-6‘,now()) from emp e where id = 1;

解释扩展例子:查询员工表中id为1员工的年龄,exp2就可以为该员工的出生年月日,并以年为单位计算。

举例:传入所查询的id参数查询工资标准(s<=6000为低工资标准;6000 <=10000为中工资标准;10000 <=15000为中上工资标准;s style=\”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;\”>=15000为高工资标准)

关于case语句,不仅仅在存储过程中可以使用,MySQL基础查询语句中也有用到过。相当于是Java中的switch语句。

loop为死循环,需要手动退出循环,我们可以使用 leave 来退出循环

可以把leave看成Java中的break;与之对应的,就有 iterate (继续循环)也可以看成Java的continue

注意:别名和别名控制的是同一个标签。

示例1:循环打印1~10(leave控制循环的退出)

注意:该loop循环为死循环,我们查的1~10数字是i,在死循环中设置了当大于等于10时停止循环,也就是说先后执行了10次该循环内的内容,结果查询了10次,生成了10个结果(1~10)。

image-20200610191639524

示例2:循环打印1~10(iterate和leave控制循环)

注意:这里我们使用字符串拼接计数器结果,而条件如果用iterate就必须时 i < 10 了!

image-20200610193153512

repeat循环类似Java中的do while循环,直到条件不满足才会结束循环。

示例:循环打印1~10

while循环就与Java中的while循环很相似了。

示例:循环打印1~10

至于流程控制的继续和结束,我们在前面已经使用过了。这里再列举一下。

游标是可以得到某一个结果集并逐行处理数据。游标的逐行操作,导致了游标很少被使用!

了解了游标的语法,我们开始使用游标。如下:

示例:使用游标查询id、name和salary。

image-20200610203622749

因为游标逐行操作的特点,导致我们只能使用游标来查询一行记录。怎么改善代码才可以实现查询所有记录呢?聪明的小伙伴想到了使用循环。对,我们试试使用一下循环。

image-20200610204034224

我们使用循环之后,发现有一个问题,因为循环是死循环,我们不加结束循环的条件,游标会一直查询记录,当查到没有的记录的时候,就会抛出异常 1329:未获取到选择处理的行数 。

如果我们想办法指定结束循环的条件该怎么做呢?

这时候可以声明一个boolean类型的标记。如果为true时则查询结果集,为false时则结束循环。

上述代码你会发现并没有写完,它留下了一个很严肃的问题。当flag = false时候可以结束循环。但是什么时候才让flag为false啊?

于是,MySQL为我们提供了一个 handler 句柄。它可以帮我们解决此疑惑。

handler句柄语法: declare continue handler for 异常 set flag = false;

handler句柄可以用来捕获异常,也就是说在这个场景中当捕获到 1329:未获取到选择处理的行数 时,就将flag标记的值改为false。这样使用handler句柄就解决了结束循环的难题。让我们来试试吧!

终极版示例:解决了多行查询以及结束循环问题。

image-20200610210925964

在执行结果中,可以看出查询结果以多次查询的形式,分布显示到了每一个查询结果窗口中。

注意:在语法中,变量声明、游标声明、handler声明是必须按照先后顺序书写的,否则创建存储过程出错。

注意:异常情况可以写异常错误码、异常别名或SQLSTATE码。

  • CONTINUE: 继续
  • EXIT: 退出
  • UNDO: 撤销
  • mysql_error_code
  • SQLSTATE [VALUE] sqlstate_value
  • condition_name
  • SQLWARNING
  • NOT FOUND
  • SQLEXCEPTION

注意:MySQL中各种异常情况代码、错误码、别名和SQLSTATEM码可参考官方文档:

https://dev.mysql.com/doc/refman/5.6/en/server-error-reference.html

需求:创建下个月的每天对应的表,创建的表格式为: comp_2020_06_01、comp_2020_06_02、…

描述:我们需要用某个表记录很多数据,比如记录某某用户的搜索、购买行为(注意,此处是假设用数据库保存),当每天记录较多时,如果把所有数据都记录到一张表中太庞大,需要分表,我们的要求是,每天一张表,存当天的统计数据,就要求提前生产这些表——每月月底创建下一个月每天的表!

预编译: PREPARE 数据库对象名 FROM 参数名

执行: EXECUTE 数据库对象名 [USING @var_name [, @var_name] …]

通过数据库对象创建或删除表: {DEALLOCATE | DROP} PREPARE 数据库对象名

在MySQL存储过程中,如果没有显示的定义characteristic,它会隐式的定义一系列特性的默认值来创建存储过程。

  • LANGUAGE SQL
  • 存储过程语言,默认是sql,说明存储过程中使用的是sql语言编写的,暂时只支持sql,后续可能会支持其他语言
  • NOT DETERMINISTIC
  • 是否确定性的输入就是确定性的输出,默认是NOT DETERMINISTIC,只对于同样的输入,输出也是一样的,当前这个值还没有使用
  • CONTAINS SQL
  • 提供子程序使用数据的内在信息,这些特征值目前提供给服务器,并没有根据这些特征值来约束过程实际使用数据的情况。有以下选择:CONTAINS SQL表示子程序不包含读或者写数据的语句NO SQL 表示子程序不包含sqlREADS SQL DATA 表示子程序包含读数据的语句,但是不包含写数据的语句MODIFIES SQL DATA 表示子程序包含写数据的语句。
  • SQL SECURITY DEFINER
  • MySQL存储过程是通过指定SQL SECURITY子句指定执行存储过程的实际用户。所以次值用来指定存储过程是使用创建者的许可来执行,还是执行者的许可来执行,默认值是DEFINERDEFINER 创建者的身份来调用,对于当前用户来说:如果执行存储过程的权限,且创建者有访问表的权限,当前用户可以成功执行过程的调用的INVOKER 调用者的身份来执行,对于当前用户来说:如果执行存储过程的权限,以当前身份去访问表,如果当前身份没有访问表的权限,即便是有执行过程的权限,仍然是无法成功执行过程的调用的。
  • COMMENT \’\’
  • 存储过程的注释性信息写在COMMENT里面,这里只能是单行文本,多行文本会被移除到回车换行等

如有死循环处理,可以通过下面的命令查看并杀死(结束)

原文链接:https://www.tuicool.com/articles/INf2qe3

数据库基础05:存储过程、触发器的创建、执行、修改与删除

  本文介绍基于Microsoft SQL Server软件,实现数据库存储过程触发器的创建、执行、修改与删除等操作。

  数据库系列文章请见专栏:。

  系列文章中示例数据来源于《 SQL Server实验指导(2005版)》一书。尊重版权,因此遗憾不能将相关示例数据一并提供给大家;但是依据本系列文章的思想与对操作步骤、代码的详细解释,大家用自己手头的数据,可以将相关操作与分析过程加以完整重现。

(1) 启动Microsoft SQL Server 2008 R2软件;

(2) 在“对象资源管理器”窗格中,在“数据库”处右键,在弹出的菜单中选择“附加”选项;

(3) 选择需要加以附加的jxsk数据库物理文件,选择定位文件夹“G:\\sql\\chutianjia sql”并选择对应数据库jxsk的物理文件并选择“确定”按钮,再次选择“确定”即可;

(4) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;右击,在弹出的窗口中选择“新建存储过程”选项;如下图;

(5) 将原有模板语句:

修改为:

(6) 单击对勾按钮进行语法检查,如下图;单击“工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(7) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;看到已存在通过上述步骤建立的存储过程;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;看到已存在通过上述步骤建立的存储过程;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(1) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;右击存储过程Pro_Qsinf,在弹出的窗口中选择“修改”选项,如下图;

(2) 将原有模板语句修改为

(3) 单击对勾按钮进行语法检查,如下图;单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;点击存储过程Pro_Qsinf,选择“参数”,可发现其定义发生变化;

(1) 在“对象资源管理器”中选择“数据库”→“jxsk”→“可编程性”→“存储过程”;右击存储过程Pro_Qsinf,在弹出的窗口中选择“删除”选项;

(2) 选择确定按钮,存储过程即被删除;如下图;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;删除后结果如下下图;

(1) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.c”;右击触发器,在弹出的窗口中选择“新建触发器”选项;如下图;

(2) 窗口内原有语句为:

需将其更改为:

(3) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(1) 查看数据库表S与SC,如下图;

(2) 删除原有S与SC之间的外键关系;修改S表中S1为S9,执行操作,如下图;

(3) 查看SC表中数据,发现其S1已改变为S9,且位置也发生相应变化,如下图;

(1) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.SC”;右击触发器,在弹出的窗口中选择“新建触发器”选项;如下图;

(2) 窗口内原有语句为:

需将其更改为:

(3) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(4) 查看数据库表S与SC,可发现在SC中有两条S号学生的记录如下两图;此时将SC中的第一条S9记录改为S1,发现修改后其数据再次恢复原有状态;如以下第三幅图;

(1) 点击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.SC”→“触发器”,可看到通过上述步骤生成的触发器已存在;如下图;

(4) 查看数据库表SC,如下图;

(5) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(6) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(7) 可以在下方窗口中看到4条系统信息,表示:第1条INSERT语句因成绩为190超出范围,而要求重新输入;第2条INSERT语句因成绩为100在正常范围内,而插入表中;第3条UPDATE语句因成绩为130超出范围,而要求重新输入;第4条UPDATE语句因成绩为60在正常范围内,修改成功;查看数据库表SC的数据。在数据库表SC数据窗口中,单击感叹号按钮,更新表SC中的数据,如下图;可以看到增加了一个记录(\’S9”,“C5’,100),修改了一条记录(\’S2\’,C5\’,60),即是步骤中SQL语句执行的结果。

(1) 点击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.C”→“触发器”,可看到通过上述步骤生成的触发器已存在;

(4) 打开数据库表C与SC,发现在SC表中有三条关于C1的记录,如下图;

(5) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(6) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(7) 在数据库表SC中发现课程C1有关的数据已经被删除;

(1) 点击“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.S”→“触发器”,右击选择“修改”选项,如下图;

(2) 窗口内原有语句为:

需将其更改为:

(3) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(4) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.S”→“触发器”,双击原有触发器,发现其已被修改;

(1) 点击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.C”→“触发器”,双击原有触发器,发现其已被修改;

(4) 在数据库表C中删除任意一条记录,发现数据库表SC与TC中记录也随之改变;

(1) 点击“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.S”→“触发器”,右击原有触发器,在弹出的菜单中选择“删除”,点击确定;

(2) 在原有位置已看不到原有触发器;

(1) 单击屏幕上方 “工具栏”菜单中的“新建查询”按钮,打开“查询编辑器”窗口,并在“查询编辑器”窗口中输入以下T-SQL语句:

(2) 单击 “工具栏”中的“执行(x)”按钮,即可执行上述T-SQL语句,如下图;

(3) 在“对象资源管理器”中选择“数据库”→“jxsk”→“表”→“dbo.C”→“触发器”,已看不到原有触发器,如下图;

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。