xml地图|网站地图|网站标签 [设为首页] [加入收藏]
支持原子DDL语句,MySQL中的存储过程
分类:数据库

   MySQL 8.0开始支持原子数据定义语言(DDL)语句。此功能称为原子DDL。原子DDL语句将与DDL操作关联的数据字典更新,存储引擎操作和二进制日志写入组合到单个原子事务中。即使服务器在操作期间暂停,也会提交事务,并将适用的更改保留到数据字典,存储引擎和二进制日志,或者回滚事务。

什么是存储过程

简单的说,就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能,类似于JAVA语言中的方法;

ps:存储过程跟触发器有点类似,都是一组SQL集,但是存储过程是主动调用的,且功能比触发器更加强大,触发器是某件事触发后自动调用;

今天遇到这样一个问题:一个系统的作业需要给系统Support人员开放SQL Agent下作业的查看、执行权限。数据库版本为SQL Server 2014 SP2,给这个系统Support人员的NT账号授予msdb数据库下面权限后:

 

有哪些特性

有输入输出参数,可以声明变量,有if/else, case,while等控制语句,通过编写存储过程,可以实现复杂的逻辑功能;

函数的普遍特性:模块化,封装,代码复用;

速度快,只有首次执行需经过编译和优化步骤,后续被调用可以直接执行,省去以上步骤;

 

 

   通过在MySQL 8.0中引入MySQL数据字典,可以实现Atomic DDL。在早期的MySQL版本中,元数据存储在元数据文件,非事务性表和存储引擎特定的字典中,这需要中间提交。MySQL数据字典提供的集中式事务元数据存储消除了这一障碍,使得将DDL语句操作重组为原子事务成为可能。

存储过程的基本格式如下:

图片 1

-- 声明结束符
-- 创建存储过程
DELIMITER $  -- 声明存储过程的结束符
CREATE PROCEDURE pro_test()    --存储过程名称(参数列表)
BEGIN
    -- 可以写多个sql语句;      -- sql语句+流程控制
    SELECT * FROM employee;
END $  -- 结束 结束符

-- 执行存储过程
CALL pro_test();   -- CALL 存储过程名称(参数);

-- 删除存储过程
DROP PROCEDURE pro_test;

参数:
IN:   表示输入参数,可以携带数据带存储过程中
OUT: 表示输出参数,可以从存储过程中返回结果
INOUT: 表示输入输出参数,既可以输入功能,也可以输出功能

图片 2

 

1. 带有输入参数的存储过程

    需求:传入一个员工的id,查询员工信息

图片 3

DELIMITER $
CREATE PROCEDURE pro_findById(IN eid INT)  -- IN: 输入参数
BEGIN
    SELECT * FROM employee WHERE id=eid;
END $ 

-- 调用
CALL pro_findById(4);

图片 4

 

2. 带有输出参数的存储过程

DELIMITER $
CREATE PROCEDURE pro_testOut(OUT str VARCHAR(20))  -- OUT:输出参数
BEGIN
        -- 给参数赋值
    SET str='hellojava';
END $

如何接受返回参数的值呢?这里涉及到MySQL的变量

 

MySQL变量一共有三种:

全局变量

全局变量又叫内置变量,是mysql数据库内置的变量 ,对所有连接都起作用。

查看所有全局变量: show variables

查看某个全局变量: select @@变量名

修改全局变量: set 变量名=新值

character_set_client: mysql服务器的接收数据的编码

character_set_results:mysql服务器输出数据的编码

 

会话变量

只存在于当前客户端与数据库服务器端的一次连接当中。如果连接断开,那么会话变量全部丢失!

定义会话变量: set @变量=值

查看会话变量: select @变量

局部变量

在存储过程中使用的变量就叫局部变量。只要存储过程执行完毕,局部变量就丢失。

 

回到上面这个存储过程,如何接受返回参数的值呢?

定义一个会话变量name, 使用name会话变量接收存储过程的返回值

CALL pro_testOut(@NAME);

查看变量值

SELECT @NAME;

 

3. 带有输入输出参数的存储过程

图片 5

DELIMITER $
CREATE PROCEDURE pro_testInOut(INOUT n INT)  -- INOUT: 输入输出参数
BEGIN
   -- 查看变量
   SELECT n;
   SET n =500;
END $

-- 调用
SET @n=10;

CALL pro_testInOut(@n);

SELECT @n;

图片 6

 

4. 带有条件判断的存储过程

需求:输入一个整数,如果1,则返回“星期一”,如果2,返回“星期二”,如果3,返回“星期三”。其他数字,返回“错误输入”;

图片 7

DELIMITER $
CREATE PROCEDURE pro_testIf(IN num INT,OUT str VARCHAR(20))
BEGIN
    IF num=1 THEN
        SET str='星期一';
    ELSEIF num=2 THEN
        SET str='星期二';
    ELSEIF num=3 THEN
        SET str='星期三';
    ELSE
        SET str='输入错误';
    END IF;
END $

--调用
CALL pro_testIf(4,@str);

SELECT @str;

图片 8

 

5. 带有循环功能的存储过程

需求: 输入一个整数,求和。例如,输入100,统计1-100的和

图片 9

DELIMITER $
CREATE PROCEDURE pro_testWhile(IN num INT,OUT result INT)
BEGIN
    -- 定义一个局部变量
    DECLARE i INT DEFAULT 1;
    DECLARE vsum INT DEFAULT 0;
    WHILE i<=num DO
          SET vsum = vsum+i;
          SET i=i+1;
    END WHILE;
    SET result=vsum;
END $

--调用
CALL pro_testWhile(100,@result);

SELECT @result;

图片 10

 

6. 使用查询的结果赋值给变量(INTO)

图片 11

DELIMITER $
CREATE PROCEDURE pro_findById2(IN eid INT,OUT vname VARCHAR(20) )
BEGIN
    SELECT empName INTO vname FROM employee WHERE id=eid;
END $

--调用
CALL pro_findById2(1,@NAME);

SELECT @NAME;

图片 12

 

图片 13

 

存储过程弊端

不同数据库,语法差别很大,移植困难,换了数据库,需要重新编写;

不好管理,把过多业务逻辑写在存储过程不好维护,不利于分层管理,容易混乱,一般存储过程适用于个别对性能要求较高的业务,其它的必要性不是很大;

...

 

官方文档:

该系统Support人员反馈在双击查看该作业时报下面错误。于是我测试,验证了一下这个权限是否OK,

 

 

图片 14

 

 

1、支持的DDL语句

我测试的时候使用的是Microsoft SQL Server Management Sutdio 2014,发现不会出现这个错误。 后面我又继续测试了一下Microsoft SQL Server Management Sutdio 2008,发现使用这个版本确实会出现这个错误,Microsoft SQL Server Management Sutdio 2008版本如下所示:

 原子DDL功能支持表和非表DDL语句。与表相关的DDL操作需要存储引擎支持,而非表DDL操作则不需要。目前,只有InnoDB存储引擎支持原子DDL。

 

 

图片 15

①:受支持的表DDL语句包括 CREATE,ALTER和 DROP对数据库,表,表和索引,以及语句 TRUNCATE TABLE声明。

 

②:支持的非表DDL语句包括:

于是我用SQL Profile跟踪了一下,双击作业操作时执行的SQL语句,如下所示

   CREATE和DROP 语句,以及(如果适用)ALTER 存储程序,触发器,视图和用户定义函数(UDF)的语句。

 

   账户管理语句: CREATE,ALTER, DROP,,如果适用, RENAME报表用户和角色,以及GRANT 和REVOKE报表。

图片 16

 

 

1.1、原子DDL功能不支持以下语句:

在执行下面SQL时,出现错误,可以将该SQL取出,在Microsoft SQL Server Management Sutdio 里面执行。

①:涉及除存储引擎之外的存储引擎的与表相关的DDL语句InnoDB。

 

②:INSTALL PLUGIN和 UNINSTALL PLUGIN 陈述。

exec master.dbo.sp_MSdbuserpriv N'serv'

③:INSTALL COMPONENT和 UNINSTALL COMPONENT 陈述。

图片 17

④:CREATE SERVER, ALTER SERVER和 DROP SERVER语句。

 

 

解决这个问题也很简单,只需要给这个NT账号,授予master数据库下面的public角色即可解决问题。

2、原子DDL特性:

①:元数据更新,二进制日志写入和存储引擎操作(如果适用)将合并为单个事务。

②:在DDL操作期间,SQL层没有中间提交。

③:在适用的情况下:

    数据字典,程序,事件和UDF高速缓存的状态与DDL操作的状态一致,这意味着更新高速缓存以反映DDL操作是成功完成还是回滚。

    DDL操作中涉及的存储引擎方法不执行中间提交,并且存储引擎将自身注册为DDL事务的一部分。

    存储引擎支持DDL操作的重做和回滚,这在DDL操作的 Post-DDL阶段执行。

④:DDL操作的可见行为是原子的,这会更改某些DDL语句的行为

 

注意:

  原子或其他DDL语句隐式结束当前会话中处于活动状态的任何事务,就好像您COMMIT在执行语句之前完成了一样。这意味着DDL语句不能在另一个事务中,在事务控制语句中执行 START TRANSACTION ... COMMIT,或者与同一事务中的其他语句结合使用。

 

3、DDL语句行为的变化

3.1、DROP TABLE:

 如果所有命名表都使用原子DDL支持的存储引擎,则操作是完全原子的。该语句要么成功删除所有表,要么回滚。

DROP TABLE如果命名表不存在,并且未进行任何更改(无论存储引擎如何),则会失败并显示错误。如下所示:

 

mysql> CREATE TABLE t1 (c1 INT);

mysql> DROP TABLE t1, t2;

ERROR 1051 (42S02): Unknown table 'test.t2'

mysql> SHOW TABLES;

+----------------+

| Tables_in_test |

本文由澳门新葡亰手机版发布于数据库,转载请注明出处:支持原子DDL语句,MySQL中的存储过程

上一篇:时间日期的一些处理方法,SQLServer某一字段时行 下一篇:没有了
猜你喜欢
热门排行
精彩图文