• 第5章——以程序方式处理MySQL数据表的数据


    处理数据表中的数据(以程序的方式)


    1、MySQL的变量

      变量是指在程序运行过程中其值可以改变的量,变量名不能与MySQL中的命令或已有的函数名称相同。

    1.1、用户变量

      用户可以在表达式中使用自己定义的变量,这样的变量称为用户变量。用户可以先在用户变量中保存值,然后在以后的语句中引用该值,这样可以将值从一条语句传递到另一条语句,用户变量在整个会话期有效。

      用户变量在使用前必须定义初始化,如果没有初始化的变量,则其值为Null。用户变量与当前连接有关,也就是说,一个客户端定义的变量不能被其他客户端使用。当客户端退出时,该客户端连接的所有变量将自动释放。

      定义和初始化一个用户变量可以使用Set语句,其语法格式如下:

    Set	@<变量名1> = <表达式1> [,@<变量名2> = <表达式2>,...];
    
    • 1

    定义和初始化用户变量的规则如下:

    1. 用户变量以”@“开始(这个要牢牢记住!),形式为”@变量名“,以便将用户变量和字段名予以区别。对于命名规则,这个就没必要再多说了;

    2. <表达式>的值是要给变量赋的值,可以是常量、变量或表达式;

    3. 用户变量的数据类型是根据其所赋予值的数据类型自动定义的,例如:

      Set @name = "adimn";
      -- 此时变量name的数据类型也为字符类型。如果重新给变量name赋值
      Set @name = 2;
      
      • 1
      • 2
      • 3
    4. 定义用户变量时变量的值可以是一个表达式,例如:

      Set @name = @name + 3;
      
      • 1
    5. 在一条定义语句中,可以同时定义多个变量,中间使用半角逗号分隔;

    6. 对于Set语句,可以使用”=“或”:=“作为赋值符,给每个用户变量赋值,被赋值的类型可以为整型、小数、字符串或Null。当然也可以使用其他的SQL语句代替Set语句为用户变量赋值,但是要注意,在这种情况下,赋值符必须使用”:=”,而不能使用“=”,原因是在非Set语句中“=”被视为比较运算符;

    7. 可以使用查询结果给用户变量赋值,例如:

      Set @name = (Select 姓名 From 学生 Where 学号 = '201607320160');
      
      • 1
    8. 在一个用户变量被定义后,它可以以一种特殊形式的表达式用于其他SQL语句,变量名前面也必须加上符合@。

      以上就是关于用户变量的知识了。难度是根本没有的,必须要记住的是创建或使用用户变量时,都必须加上符合@!

    1.2、系统变量

      什么是系统变量?顾名思义,就是系统定义好的变量。系统变量在MySQL服务器启动时就被引入并初始化为默认值。系统变量一般以“@@”为前缀,如@@Version返回MySQL的版本。但某些特定的系统变量可以省略“@@”符号,如Current_Date(系统日期)、Current_Time(系统时间)、Current_Timestamp(系统日期和时间)和Current_User(当前用户名)。

    要查询它们自然是使用Select语句来进行查询了。就如下实例:

    SELECT @@Version,CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER;
    
    • 1

    在这里插入图片描述

      系统变量的值自然也是能够进行修改的,当然也有一些系统变量的值是不能修改的,如Version和系统日期。要进行修改系统变量可以使用Set语句来修改。其语法格式如下:

    Set	<系统变量名>=<表达式>
    	| [Global | Session] <系统变量名>=<表达式>
    	| @@[Global | Session] <系统变量名>=<表达式>;
    
    • 1
    • 2
    • 3

      系统变量可以分为全局变量会话系统变量两种类型。对于这两种类型,使用Global或“@@global.”关键字的是全局系统变量,使用Session或“@@session.”关键字的是会话系统变量。Session和@@session还有一个同义词Local和“@@local.”。如果在使用系统变量时不指定关键字,则默认为会话系统变量。只有具有super权限才可以设置全局变量。

    • 显示所有系统变量的语句为Show Variables;
    • 显示所有全局系统变量的语句为Show Global Variables;
    • 显示所有会话系统变量的语句为Show Session Variables;
    • 要显示与样式匹配的变量名称或名称列表,需使用Like子句和通配符“%”,例如:
    Show Variables Like 'character%';
    
    • 1
    1. 全局系统变量:当MySQL启动的时候,全局系统变量就被初始化了,并且应用于每个启动的会话。全局系统变量对所有客户端有效,其值能应用于当前连接,也能应用于其他连接,直到服务器重新启动为止;
    2. 会话系统变量:会话系统变量对当前连接的客户端有效,只是适用于当前的会话。会话系统变量的值是可以改变的,但是其新值仅适用于正在运行的会话,不适用于其他会话。

    ​ MySQL中大多数系统变量有默认值,当数据库服务器启动时,就使用这些默认值。如果要将一个系统变量的值设置为MySQL的默认值,则可以使用Default关键字。

    -- 例如,将系统变量SQL_Select_Limit的值恢复为MySQL的默认值的语句如下:
    Set @@Session.SQL_SELECT_LIMIT = Default;
    
    • 1
    • 2

      由此,我们可以得出:Java中的Default与MySQL中的Default的用法和意思都是不同的。在Java中,Default是访问修饰符,是用来修饰方法的,不能用来修饰类;而在MySQL中,Default是一个关键字,用来为系统变量设置默认值。

    1.3、局部变量

      局部变量是可以保存单个特定类型数据值的变量,其有效作用范围为存储过程和自定义函数的Begin到End语句块之间,在Begin…End语句块运行完之后,局部变量就消失了,其他语句块中不可以使用该局部变量,但Begin…End语句块内所有语句都可以使用(其实这跟Java中的局部变量是一个意思的,Java中的局部变量也只能在方法体中才能使用)。

      MySQL中局部变量必须先定义后使用。使用Declare语句声明局部变量,定义局部变量的语法格式如下:

    Declare <变量名称> <数据类型> [Default<默认值>];
    
    • 1

      Default子句给变量指定一个默认值,如果不指定,则默认为Null。

      局部变量名称必须符合MySQL标识符的命名规则,在局部变量前面不使用@符号。该定义语句无法单独执行,只能在存储过程和自定义函数中使用。例如:

    Declare	name varchar(30);
    -- 可以使用1个语句提示声明多个变量,如下
    Declare name varchar(20), number int, sex char(1);
    
    • 1
    • 2
    • 3

      可以使用Set语句为局部变量赋值,Set语句也是SQL本身的一部分,其语法格式如下:

    Set	<局部变量名> = <表达式>;
    
    -- 例如
    Set name = '安徽', number = 2, sex = '男';
    
    • 1
    • 2
    • 3
    • 4

    注意:局部变量在赋值之前必须使用Declare关键字声明。(其实就是要先创建出局部变量,之后才能进行赋值)

    也可以使用Selec…Into语句将获取的字段值赋给局部变量,并且返回的结果只能有一条记录值,其语法格式如下:

    Select <字段名>[,...]	Into<局部变量名>[,...]	[From子句][Where子句];
    
    • 1

    例如:

    Select Sum(借出数量) Into number From 图书借阅;
    
    • 1

      使用Select语句给变量赋值时,如果省略了From子句和Where子句,就等同于Set语句赋值。如果有From子句和Where子句,并且Select语句返回多个值,则只将返回的最后一个值赋给局部变量。

    2、MySQL的运算符与表达式

    2.1、运算符

      对于MySQL中的运算符,其实没什么好说的,这些都与Java中的运算符都是一样的,基本上没什么变换。所以只要知道Java中的运算符,那么对于MySQL中的运算符就没什么问题了。

    在这里,我们需要补充的是:一元运算符。

    一元运算符只对一个表达式执行操作,该表达式可以是数值类型中的任何一种数据类型。MySQL中的一元运算符有:+(正)、-(负)和~(位取反)。

    2.2、表达式

      表达式是常量、变量、字段值、运算符和函数的组合,MySQL可以对表达式求值以获取结果,一个表达式通常可以得到一个值。与常量和变量一样,表达式的值也具有某种数据类型,可能的数据类型有字符类型、数值类型、日期时间类型等。这样,根据表达式值的类型,表达式可分为字符型表达式数值表达式日期表达式

    2.3运算符的优先级

      对于MySQL中运算符的优先级,也是没有必要进行过多的解释。这些都和Java是相似的。

    3、MySQL的控制语句

    3.1、Begin…End语句

      MySQL中Begin…End语句用于将多个SQL语句组合为一个语句块,相当于一个单一语句,达到一起执行的目的。

    Begin…End语句的语法格式如下:

    Begin
    	<语句1>
    	<语句2>
    	...
    End
    
    • 1
    • 2
    • 3
    • 4
    • 5

    MySQL中允许嵌套使用Begin…End语句。

    3.2、If…Then…Else语句

      If…Then…Else语句用于进行条件判断,实现程序的选择结构。根据是否满足条件,将执行不同的语句,其语法格式如下:

    If <条件表达式1> Then <语句块1>
    [Else <条件表达式2> Then <语句块2>]
    [Else <语句块3>]
    End If;
    
    • 1
    • 2
    • 3
    • 4

    这个If…Then…Else语句其实就是Java中的If判断语句,执行的原理和Java是一模一样的。

    3.3、Case语句

      Case语句用于计算列表并返回多个可能结果表达式中的一个,可用于实现程序的多分支结构,虽然使用If…Then…Else语句也能实现多分支结构,但是使用Case语句的程序可读性更强,一条Case语句经常可以充当一条If…Then…Else语句。与If…Then…Else语句相比,Case语句是平行的。

    MySQL中,Case语句有以下两种形式。

    (1)简单Case语句

      简单Case语句用于将某个表达式与一组简单表达式进行比较以确定其返回值,其语法格式如下:

    Case <输入表达式>
    	When <表达式1>	Then <SQL语句1>
    	When <表达式2> Then <SQL语句2>
    	...
    	[Else <其他SQL语句>]
    End Case;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      简单Case语句的执行过程:将“输入表达式”与各个When子句后面的“表达式”进行比较,如果相等,则执行相对应的SQL语句,然后并跳出Case语句,不再执行后面的When子句;反之,如果没有相等,就执行Else子句后面的“其他SQL语句”。如果没有指定Else子句,则没有执行Case语句内任何一条SQL语句。我们可以发现,简单Case语句的执行原理和Java中的Switch…case语句是相同的。

    (2)搜索Case语句

    搜索Case语句用于计算一组逻辑表达式以确定返回结果,其语法格式如下:

    Case
    	When <逻辑表达式1> Then <SQL语句1>
    	When <逻辑表达式2> Then <SQL语句2>
    	...
    	[Else <其他SQL语句>]
    End Case;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      搜索Case语句的执行过程:搜索Case语句中的When子句相互不受影响,只要有一个When子句后的“逻辑表达式”的结果为true,就可执行相对应的SQL语句,换句话来说,就是有多少给“逻辑表达式”的结果为true,就可以执行多少给SQL语句。如果其结果都为false,那么就执行Else子句后面的“其他SQL语句”。如果没有指定Else子句,则没有执行Case语句内任何一条SQL语句。这就是与Java中的Switch…case语句的不同之处。

    3.4、While循环语句

      While循环语句用于实现循环结构,是有条件控制的循环语句,但满足某种条件时执行循环体内的语句。While语句的语法格式如下:

    [开始标注:]
    While <逻辑表达式> Do
    	<语句块>
    End While[结束标注];
    
    • 1
    • 2
    • 3
    • 4

      MySQL的While循环语句与Java中的While循环语句的执行原理是相同的。这里要注意的是:“开始标注:”和“结束标注”是while语句的标注,除非“开始标注:”存在,否则“结束标注”不能出现,并且如果两者都出现,则它们的名称必须是相同的。当然,这两者通常都是可以省略的。(这在Java中的While循环语句是没有的,也是它的不同之处)

    3.5、Repeat循环语句

      Repeat循环语句是有条件控制的循环语句,当满足特定条件时,就会跳出循环语句。Repeat语句的语法格式如下:

    [开始标注:]
    Repeat <语句块>
    Until <逻辑表达式>
    End Repeat[结束标注];
    
    • 1
    • 2
    • 3
    • 4

      Repeat循环语句的执行过程:首先执行语句块中的语句,然后判断逻辑表达式的值是否为True,为True则停止循环;为False则继续循环。Repeat语句也可以被标注。Repeat语句与While语句的区别是:Repeat语句先执行语句,再进行条件判断;而While语句先进行条件判断,条件为True时才执行语句。(其实这和Java中的do…while循环语句是相似的,唯一的差别是:Java中do…while语句是判断条件为True时,才会进行循环下去;而MySQL中Repaet语句是判断条件为False时,才会进行循环下去。记住,这两者不能混淆!!!)。

    3.6、Loop循环语句

      Loop语句可以使某些语句重复执行,实现一些简单的循环。但是Loop语句本身没有停止循环的机制,必须遇到Leave语句才能停止循环。Loop语句的语法格式如下:

    [开始标注:]
    Loop <语句块>
    End Loop[结束标志];
    
    • 1
    • 2
    • 3

      Loop语句允许某特定语句或语句块重复执行,实现一些简单的循环结构。在循环体内的语句一直重复执行直到循环被强迫终止,终止通常使用Leave语句。

    3.7、Leave语句

      Leave语句主要用于跳出循环控制,经常和循环一起使用,其语法格式如下:

    Leave <标注名>;
    
    • 1

    使用Leave语句可以退出被标注的循环语句,标注名是自定义的。

    3.8、Iterate语句

    Iterate语句主要用于跳出本次循环,然后直接进入下一次循环,其语法格式如下:

    Iterate <标注名>;
    
    • 1

      Iterate语句与Leave语句都是用来跳出循环语句的,但两者的功能不一样,其中Leave语句用来跳出整个循环,然后执行循环语句后面的语句;而Iterate语句是跳出本次循环,然后进行下一次循环。

    4、MySQL系统定义的内置函数

      MySQL中包含100多个内置函数,从数学函数到比较函数等。所以就没有必要做笔记了。

    5、MySQL的存储过程

    5.1、存储过程的概念

      存储过程是一段为了完成特定功能的程序,通过存储过程可以将经常使用的SQL语句封装起来,这样可以避免重复编写相同的SQL语句,存储过程可以由声明式SQL语句(如Create、Update、Select等)和过程式SQL语句(如If…Then…Else语句组成)。另外,存储过程一般是经过编译后存储在数据库中的,所以执行存储过程要比执行存储过程中封装的SQL语句效率更高。存储过程还可以接收输入参数、输出参数等,可以返回单个或多个结果集。存储过程可以由程序、触发器或者另一个存储过程来调用,从而激活它,实现代码段中的SQL语句。

    5.2、存储过程的优点

    ①执行速度快:存储过程比普通SQL语句功能更强大,而且能够实现功能型编程,可以提高SQL语句的执行效率;
      
    ②封装复杂的操作:存储过程中允许包含一条或多条SQL语句,利用这些SQL语句完成一个或多个逻辑功能。也就是说,我们可以之间调用存储过程来使用SQL语句,因为存储过程中封装了SQL语句(与Java中的封装很相似);
      
    ③有很强的灵活性:存储过程可以用流程控制语句编写,可以完成较复杂的判断和运算;
      
    ④使数据独立:程序可以调用存储过程,来代替执行多态SQL语句。在这种情况下,存储过程把数据同用户隔离开来,其优点是当数据表的结构改变时,调用者不用修改程序,只需要重新编写存储过程即可;
      
    ⑤提高安全性:存储过程可被作为一种安全机制来充分利用,系统管理员通过限制存储过程的访问权限,从而实现相应数据的访问权限限制,避免了非授权用户对数据的访问,保证了数据的安全;
      
    ⑥提高性能:复杂的功能往往需要多条SQL语句才能实现,同时客户端需要多次连接并发送SQL语句到服务器才能完成该功能。如果利用存储过程,则可以将这些SQL语句放入存储过程中,当存储过程被成功编译后,就存储在数据库服务器中,以后客户端可直接调用,这样所有的SQL语句都可在服务器中执行;
      
    ⑦存储过程能减少网络流量:针对同一个数据库对象的操作,如果这一操作所涉及的SQL语句被组织成存储过程,那么当在客户机上调用该存储过程时,网络中传送的只是改调用语句,从而大大降低了网络负载。

    5.3、Delimiter命令

      Delimiter命令用于更改MySQL语句的结束符,如将默认结束符“;”更改为“$$”,避免与SQL语句默认结束符相冲突。其语法格式如下:

    Delimiter <自定义的结束符>
    
    • 1

      用户自定义的结束符可以是一些特殊的符号,如“$$”、“##”,“//”等,但应避免使用反斜杠“\”字符,因为“\”是MySQL的转义字符。

    恢复使用MySQL的默认结束符“;”的命令如下:

    Delimiter ;
    
    • 1

    5.4、创建存储过程

    创建存储过程的语法格式如下:

    Create Procedure <存储过程名>([<参数列表>])
    	[<存储过程的特征设置>]
    	<存储过程体>
    
    • 1
    • 2
    • 3

    说明:

    一:其存储过程的命名规则就没什么好说的,一定要避免使用与MySQL的内置函数相同的名称。通常存储过程默认在当前数据库中创建,如果需要在特定的数据库中创建,则需在存储过程名前面加上数据库的名称,即<数据库名>.<存储过程名>;

    二:存储过程可以不使用参数,也可以带上一个或多个参数。无论是否带参数,存储过程名后面的括号都不可省略。当有多个参数,其参数的定义格式如下:

    [In | Out | InOut] <参数名> <参数类型>
    
    • 1

      在MySQL中,存储过程支持3种类型的参数:输入类型参数、输出类型参数和输入\输出类型参数,关键字分别使用In、Out、InOut,默认的参数类型为In。输入参数使数据可以传递给存储过程;存储过程使用输出类型参数,把存储过程内部的数据传递给调用者;输入\输出参数既可以充当输入参数,也可以充当输出参数,既可以把输出传入到存储过程中,也可以把存储过程中的数据传递给调用者。注意,存储过程的参数名不要使用数据表中的字段名,否则SQL语句会把参数看做字段名,从而引发不可预估的结果;

    三:存储过程的特征设置的格式如下:

    Language SQL
    | [Not] Deterministic
    | {Contains SQL | Not SQL | Reads SQL Data | Modifies SQL Data}
    | SQL Security  {Definer | Invoker}
    | Comment <注释信息内容>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    各参数的含解释如下:

    Language SQL:表明编写该存储的语言为SQL。由于MySQL存储过程还不能使用其他编程语言来编写,所以该选项可不选定;
      
    Deterministic:使存储过程对同样的输入参数产生相同的结果;
      
    Not Deterministic:为默认设置,对同样的输入参数会产生不确定的结果;
      
    Contains SQL:为默认设置,表示存储过程包含SQL语句,但不包含读或写数据的语句;
      
    Not SQL:表示存储过程不包含SQL语句;
      
    Reads SQL Data: 表示存储过程包含读数据的语句,但不包含写数据的语句;
      
    Modifies SQL Data:表示存储过程包含写数据的语句;
      
    SQL Security:用来指定谁有权限来执行,Definer表示只有该存储过程的定义者才能执行,Invoker表示拥有权限的调用者可以执行。默认情况下,系统指定为Definer;
      
    Comment <注释信息内容>:注释信息,可以用来描述存储过程。

    四:存储过程体是存储过程的主体部分,其内容包含了可执行的SQL语句,这些语句总是以Begin开始,以End结束。当然,当存储过程中只有一条SQL语句时,可以省略Begin…End语句。

      存储过程体中可以使用所有类型的SQL语句,包括DLL、DCL和DML语句。也可以使用过程式语句,同样包括变量的定义和赋值语句。

    5.5、查看存储过程

    查看存储过程状态的语法格式如下:

    Show Procedure Status[Like <存储过程名的模式字符>];
    
    • 1

    查看存储过程定义的语法格式如下:

    Show Create Procedure<存储过程名>;
    
    • 1

    5.6、调用存储过程

    存储过程创建完成后,可以在出程序。触发器或者其他存储过程中被调用。其语法格式如下:

    Call <存储过程名>([<参数列表>]);
    
    • 1

      如果需要调用某个特定数据库的存储过程,则需要在存储过程名前面加上该数据库的名称。如果定义存储过程时使用了参数,则调用该存储过程时,也要使用参数,并且参数个数和顺序都要相对应。

    5.7、修改存储过程

    可以使用Alter Procedure语句修改存储过程,其语法格式如下:

    Alter Procedure<存储过程名> [<存储过程的特征设置>];
    
    • 1

    修改存储过程中的特征设置与创建存储过程的类似。

    如果要修改存储过程的存储过程体内容,则可以先删除该存储过程,再重新定义。

    5.8、删除存储过程

    在命令行中删除存储过程的语法格式如下:

    Drop Procedure [if exists]<存储过程名>;
    
    • 1

    其中,if exists子句可以防止存储过程不存在时出现警告信息。

    注意:在删除存储过程之前,必须确认该存储过程没有任何依赖关系,否则导致其他与之关联的存储过程无法执行。

    6、MySQL的自定义函数

    MySQL允许用户自定义函数,补充和扩展系统支持的内置函数,用户自定义函数可以实现模板化程序设计,并且执行速度更快。

    6.1、自定义函数概述

      MySQL的自定义函数与存储过程相似,都是由SQL语句和过程式语句组成的代码片段,并且可以在应用程序中调用。当然,它们自然是存在区别的。区别如下:

    1. 自定义函数不能拥有输出参数,因为函数本身就有返回值;
    2. 不能使用Call语句调用函数;
    3. 函数必须包含一条Return语句,而存储过程不允许使用该语句。

    6.2、自定义函数的定义

    创建自定义函数的语法格式如下:

    Create Function <函数名>([<输入参数名>	<参数类型>[,...]])
    	Returns<函数返回值类型>
    	[<函数的特征设置>]
    	<函数体>
    
    • 1
    • 2
    • 3
    • 4

    同样和创建存储过程一样,也是有需要注意的地方。

    1. 定义函数时,其函数名自然是不能与MySQL中的关键字、内置函数、已有的存储过程、已有的自定义函数同名;
    2. 自定义函数可以有输入参数,也可以没有输入参数,可以带一个输入参数,也可以带多个输入参数,参数必须规定参数名和类型;
    3. 自定义函数必须有返回值,Returns后面就是设置函数的返回值类型;
    4. 自定义函数的函数体可以包含流程控制语句、游标等,但必须包含Return语句,返回函数的值;
    5. 函数的特征设置与存储过程类似,可以借助存储过程的特征设置来理解。

    6.3、查看自定义函数

    查看自定义函数状态的语法格式如下:

    Show Function Status[Like <函数名的模式字符>];
    
    • 1

    查看自定义函数的语法格式如下:

    Show Create Function<函数名>;
    
    • 1

    6.4、调用自定义函数

      自定义函数创建成功后,就可以进行调用了。其调用的方法与调用MySQL的内置函数是一样的,不一样的地方是所使用的关键字不相同,调用自定义函数的语法格式如下:

    Select函数名称([实参]);
    
    • 1

    6.5、修改自定义函数

    修改函数是指修改已定义好的自定义函数,其语法格式如下:

    Alter Function <自定义函数名>[<函数的特征设置>];
    
    • 1

    如果要修改自定义函数的函数体内容,则可以采用先删除后重新定义的方法。

    6.6、删除自定义函数

    删除自定义函数的语法格式如下:

    Drop Function [if exists]<自定义函数名>;
    
    • 1

    7、MySQL的游标

      为了方便用户对结果集中单条记录行进行访问,MySQL提供了一种特殊的访问机制:游标。游标主要包括游标结果集游标位置两部分。其中,游标结果集是指由定义游标的Select语句所返回的记录集合;游标相当于指向这个结果集中某一行的指针。

      查询语句可能查询多条记录,在存储过程和函数中使用游标来逐条读取查询结果集中的记录。游标的使用包括声明游标、打开游标、使用游标和关闭游标。游标一定要在存储过程或函数中使用,不能单独在查询中使用。

    7.1、声明游标

    MySQL中,声明游标的语法格式如下:

    Declare <游标名> Cursor For <Select语句>
    
    • 1

      游标名称必须符合MySQL标识符的命名规则,Select语句返回一行或多行记录数据,但不能使用Into子句。该语句声明一个游标,也可以在存储过程中定义多个游标,但是一个语句块中的每个游标都有自己唯一的名称。

    7.2、打开游标

      声明游标后,要使用游标从中提前数据,就必须要打开游标,在MySQL中,使用Open语句打开游标,其语法格式如下:

    Open <游标名>;
    
    • 1

      在程序中,一个游标可以打开多次,由于其他的用户或程序本身已经更新了数据表,所以每次打开的结果可能不同。

    7.3、读取游标

    游标打开后,可以使用“Fetch…Into”语句从中读取数据,其语法格式如下:

    Fetch <游标名> Into <变量名1>[,<变量名2>,...];
    
    • 1

      Fetch语句将游标指向的一行记录的一个或多个数据赋给一个变量或多个变量,子句中变量的数目必须等于声明游标时Select子句中字段的数目。变量名必须在声明游标之前就定义完成。

    7.4、关闭游标

    游标使用完以后需要及时关闭,其语法格式如下:

    Close <游标名>;
    
    • 1

    8、MySQL的触发器

    8.1、触发器的概念

      触发器是一种特殊的存储过程,它与数据表紧密相连,可以看做数据表定义的一部分,用于数据表实施完整性约束。触发器建立在触发事件上,如对数据表执行Insert、Update或者Delete等操作时,MySQL就会自动执行建立在这些操作上的触发器。在触发器中包含了一系列用于定义业务规则的SQL语句,用来强制用户实现这些规则,从而确保数据的完整性。

      存储过程可以使用Call命令调用,触发器的调用和存储过程不一样,触发器只能由数据库的特定事件来触发,并且不能接收参数。当满足触发器的触发条件时,数据库系统就会执行触发器中定义的程序语句。

    8.2、创建触发器

    MySQL中创建触发器的语法格式如下:

    Create Trigger<触发器名> Before|After<触发事件>
    	On<表名> For Each Row<执行语句>;
    
    • 1
    • 2

    说明:

    1. 触发器名称在当前数据库中必须具有唯一性,如果需要在指定的数据库中创建触发器,则在触发器名称前加上数据库的名称;
    2. Before | After以表示触发器在激活它的语句之前触发还是之后触发;
    3. 触发事件指明了激活触发程序的语句类型,通常为Insert(新插入记录时激活触发器)、Update(更改记录数据时激活触发器)、Delete(从数据表中删除记录时激活触发器);
    4. 表名表示与触发器相关的数据表名称,在该数据表上发生触发事件才会激活触发器。需要注意的是:同一个数据表中不能拥有两个具有相同触发时刻和事件的触发器。也就是说,可以有一个Before Update触发器和一个Before Insert触发器,也可以有Before Update触发器和一个After Update触发器,但就是不能有两个Before Update触发器;
    5. For Each Row指定对于受触发事件影响的每一行,都要激活触发器的动作;
    6. 执行语句为触发器激活时将要执行的语句,如果要执行多条语句,则可以使用Begin…End复合语句,这样就能使用存储过程中允许的语句。

    注意: 触发器不能返回任何结果到客户端,为了阻止从触发器返回结果,不要在触发器定义中包含Select语句。同样,也不能调用将数据返回客户端的存储过程。

      MySQL触发器中的SQL语句可以关联数据表中的任意字段,但不能直接使用字段名称,这样做系统会无法识别,因为激活触发器的语句可能已经修改、删除或添加了新字段名,而字段的原名称同时存在。因此必须使用“New.<字段名>”或“Old.<字段名>”标识字段,“New.<字段名>”用来引用新记录的一个字段,“Old.<字段名>”用来引用更新或删除该字段自之前原有的字段。对于Insert语句,只有New可以使用;对于Delete语句,只有Old才可以使用;对于Update语句,New和Old都可以使用。

    8.3、查看触发器

      查看触发器是指查看数据库中已存在的触发器的定义、状态和语法信息等,可以使用语句来查看已经创建的触发器。

    1. 使用Show Triggers 查看触发器;
    2. 使用Select语句查看Triggers数据表中的触发器信息,其语法格式如下:
    Select * From Information_Schema.Triggers Where Trigger_Name = <触发器名>;
    
    • 1

    8.4、删除触发器

    删除触发器的语法格式如下:

    Drop Trigger[<数据库名>.]<触发器名>;
    
    • 1

    如果省略了数据库名,则表示在当前数据库中删除指定的触发器。

    9、MySQL的事务及其控制语句

      使用事务可以将一组相关的数据操作捆绑成一个不可分割的整体,一起执行或一起取消。事务是单个的工作单元,在事务中可以包含多条操作语句。如果对事务执行提交,则该事务中进行的所有操作均会提交,称为数据库中的永久组成部分。如果事务中的一条语句遇到错误不能执行而被取消或回滚,则事务中的所有操作均被清除,数据恢复到事务执行前的状态。

    9.1、事务的特性

    事务主要有4个特性,可以简称ACID特性。

    1. 原子性(Atomicity):事务必须是不可分割的原子工作单元,对于其数据修改,要么全都执行,要么全都不执行;
    2. 一致性(Consistency):事务在完成时,使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构都必须是正确的;
    3. 隔离性(Isolation):由并发事务所做的修改必须与任何其他并发事务所做的修改隔离;
    4. 持久性(Durability):事务完成之后,它对于系统的影响是永久的。

    9.2、开始事务

    Start Transaction语句和Begin Work语句用于显式地启动一个事务。其语法格式如下:

    Start Transaction | Begin Work
    
    • 1

    9.3、结束事务

      Commit语句标志一个成功执行的事务结束,用于提交事务,将事务所做的数据修改保存到数据库中。其语法格式如下:

    Commit[Work][And[No]Chain][[No]Release]
    
    • 1

      其中,可选项And Chain子句会在当前事务结束时,立刻启动一个新事务,并且新事务与刚结束的事务有相同的隔离等级。Release子句在终止了当前事务后,会让服务器断开当前客户端的连接。包含No关键字可以抑制Chain或Release完成。

    9.4、撤销事务

    Rollback语句用于撤销事务所做的修改,并结束当前事务。其语法格式如下:

    Rollback[Work][And[No]Chain][[No]Release]
    
    • 1

    9.5、设置保存点

    Savepoint语句用于在事务内设置保存点。其语法格式如下:

    Savepoint<保存点名称>
    
    • 1

    9.6、回滚事务

      Rollback To语句将事务回滚到事务的起点或事物内的某个保存点,用于取消事物对数据的修改。Rollback To Savepoint语句会向已命名的保存点回滚一个事物。如果在保存点被设置后,当前事务对数据进行了修改,则这些更改会在回滚中被撤销。其语法格式如下:

    Rollback[Work]To Savepoint<保存点名称>
    
    • 1

    当事务回滚到某个保存点后,在该保存点之后设置的保存点将被删除。

    Rollback Savepoint语句会从当前事务的一组保存点中删除已命名的保存点。其语法格式如下:

    Rollback Savepoint<保存点名称>
    
    • 1
  • 相关阅读:
    Flink 命令行参数介绍
    Linux下lt9611调试总结资料分享
    【硅谷甄选】P44 element-plus 含有多个子菜单的菜单的折叠字体图标溢出
    绁炵粡缃戠粶浠跨湡鐮旂┒鍗氬+璁烘枃涓嬭浇
    数据库执行计划与更新统计信息(AI问答)
    基于Java毕业设计长鸟交易市场信息平台源码+系统+mysql+lw文档+部署软件
    21天Python进阶学习挑战赛打卡------第4天(字典)
    如何实现设备可视化系统建设?
    Linux kprobe原理
    在全新ubuntu上用gpu训练paddleocr模型遇到的坑与解决办法
  • 原文地址:https://blog.csdn.net/weixin_49794837/article/details/126074453