DCL
简介:很多时候一个数据库需要多人进行控制和操作,这时就需要使用数据控制语言来创建账户以及分配可使用权限,可见该语言主要涉及2个问题:
- 用户管理
- 权限分配
mysql中的权限
首先理解什么是权限,简单来说就是可执行的操作,在mysql中主要用某种字段的开或者关来表示是否有某种权限,权限名如:’select’, ‘update’,大约有30个。
主要权限如下:
mysql中的用户
Mysql中可使用数据库的帐户信息在系统数据库mysql中的user表中:
创建用户:
语法:
Create user ‘用户名’@‘允许其登录的ip地址’ identified by ‘密码’;
解释说明:
- User信息表示创建的用户的用户名及可以登录数据库的ip地址,‘%’表示任何地址
- 用户创建之后,自动在mysql的user表中添加了一条记录,但没有权限
删除用户:
语法:
Drop user ‘用户名’@’允许其登录的地址’
修改用户密码:
修改自己密码:set password = password(‘新密码’);
修改他人密码(在右修改权限条件下):
Set password for ‘用户名’@’允许其登录的地址’ = password(‘新密码’);
权限分配
增加权限:
简单地说就是赋予某个用户对数据库可执行某种操作的权限
语法:
Grant 权限1, 权限2, …… on 数据库名.对象名 to ‘用户名’@‘允许其登录的地址’ identified by ‘密码’;
解释说明:
- 权限名:’select’, ‘update’, ‘delete’,等等。其中ALL表示”所有权限”,与all privileges也一样
- 对象名:数据库中含有的例如‘表’,‘视图’,‘存储函数’,‘存储过程’等,其中*代表所有
- Identified by ‘密码’ 用于给一个用户修改密码,不写也行
- 注意该语句同时也有创建该用户并同时分配权限的作用,此时identified by ‘密码’必须写
删除权限:
语法:
Revoke 权限名1,权限名2,…… on 数据库名 . 对象名 from ‘用户名’@‘允许其登录的地址’
事务控制语言
什么是事务
在之间的mysql语句中,我们对mysql的每条操作语句都是操作及执行即结束,那么就可以说这种“一次性执行并结束”的过程称为“一个事务”,即“一条SQL语句即一个事务”。
然而,在很多工作场合,我们需要让“多条SQL语句”看成“一条SQL语句”(表示只有所有的sql语句要么都执行成功要么都执行失败然后结束),工作中的事务就是如此。
事务的作用
举例一个实际应用需求(银行存款):表名cunkuan
| id | 账户名 | 存款 |
| 1 | test1 | 1000 |
| 2 | test2 | 5000 |
| 3 | test3 | 3000 |
现在,假如test1急需4000块并向test2借款,银行操作对应的sql语句如下:
第一步:update cunkuan set 存款=存款-4000 where id = 2;
遇突发事件突然中止
第二步:update cunkuan set 存款=存款+4000 where id = 1;
如果没有事务的话,以上情况就会发生,有事务则可以避免以上事情
事务起的作用:只有两步单独执行都成功才能真正对数据库进行操作否则撤回以上操作
事务的特点:
- 原子性:一个事务中所有语句要么全做,要么都不做
- 一致性:数据保持逻辑上的“合理性”,比如:一个商品出库时,既要让商品库中的该商品数量减1,又要让对应用户的购物车的该商品加1
- 隔离性:如果多个事务同时并发执行,每个事务应保持独立运行
- 持久性:一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)
事务模式:
事务模式:将sql执行语句是否当作一个事务的设定项(Mysql安装好以后默认事务模式:一条语句当作一个事务)
比如:
原来数据:
执行插入:
结果:
如需要把多条语句设定为一个事务:事务需要“认可”模式
Set autocommit = 0; //false,关闭该模式,即此时不再是一条语句一个事务了
//结果是:必须使用commit 语句才能够生效
特别注意:事务模式有的存储引擎不支持(存储引擎就是将数据存入硬盘(或其他媒介)的方式方法)
Mysql默认是Innodb
然后插入:
没有变化:
执行:
结果为:
注意:autocommit的设置值,只是影响通常情况下都每条语句的默认行为(自动提交还是等着commit提交)
不管autocommit的值是什么(1,0),我们也仍然可以使用事务的完整流程模式来实现事务,如下:
事务的基本实现流程
- 声明事务开始:start transaction;
- 设定多条要执行的具体语句,比如:insert, update, delete, select ……其实就是执行,只是这些执行的语句并不生效—其实只是内存状态下的执行,而不是物理状态的执行。
- 判断是否需要执行该些语句;
If(判断是否有错误){
//执行—才针对执行物理性改变—即生效
Commit;
}
Else{
//回滚—不执行任何语句。
Rollback;
}
判断是否有错误通常分为这两种环境:
1,如果是cmd中,直接观察是否出错
2,如果是php程序中,那就需要使用mysql_error()函数来判断是否有错
下来使用事务完整转账这件事情(假设为cmd模式):
Start transaction;
#第一步:
Update cunkuan set 存款=存款 -4000 where id=2;
#第一步做完,有意外情况中断
#第二步
Update cunkuan set 存款=存款+4000 where id =1;
如果这两条语句都没有错误,就可以:
Commit;
但如果其中发生了错误,则可以:
Rollback;
mysql编程
基本语法形式:
语句块模式:
在mysql编程,begin……end;基本代替了原来编程语句中的{……}语法.
但有所区别:一个begin…end;块,可以给定一个“标识符”,并且可以使用leave语句来“退出”该语句块
基本流程控制语句:
if语句:
case语句:
while循环语句:
mysql中的变量:
Mysql中的变量有一定的使用范围限制(其中包括前面的流程控制语句):在通常的执行各种create, insert, delete, update, select 等语句的“环境”中,并不使用常规变量也不能使用流程控制字句,这种环境可被称作命令环境
而那些变量及流程控制字句的使用环境为编程环境:存储函数中,存储过程中,触发器中
普通变量的声明语法:
Declare 变量名 变量类型 [default 初始值]
变量的赋值语法:
Set 变量名 = 变量值
Mysql还有一种变量形式,可以被称为“会话变量”,这种变量既能在命令行环境下也能在编程环境下使用
会话变量的形式为:@变量名;会话变量无需声明可直接赋值;会话变量的赋值:set 变量名 = 值;
- 语法1:set 变量名 = 表达式; #此语法中的变量必须先使用declare声明
- 语法2:set @变量名 = 表达式;#此方式无需declare声明
- 语法3:set @变量名 :=表达式;#此语句会给变量赋值,同时还会作为select语句输出结果
- 语法4:select 表达式 into @变量名;#此语句虽然看起来是select语句,但其实并不输出结果集只是给变量赋值
当然也可以进行运算:
总结
SQL语句可在两种环境中运行(不是指编辑器和cmd命令行,而是指都在cmd命令行或编辑器的两种环境):
- 常规:执行增删改查
- 编程环境:特定的语句语法内部:存储过程、存储函数、触发器
两种变量:
- 普通变量:不带@符,先声明后赋值,只能用于编程环境
- 会话变量:带@符,无需声明,直接使用,可用于两种环境
流程控制语句:只能用于编程环境
存储函数:
就是在数据库中存储一个函数来实现某种功能,等级跟表类似
定义形式:
调用形式:跟系统函数的调用形式一样直接使用名字并带括号,以及根据需要带相应实参
select 3, now(), f1(); //f1为自定义的存储函数
Select 3, now(), f2(3, ‘abc’, @v1); //带3个实参,其中@v1是一个前面赋值了的变量
举例:
需要设定结束符以完成操作
- 删除:drop function [ if exists]存储函数名;
存储过程
存储过程就是一个没有返回数据值的“函数”:虽然存储过程不返回单个数据值,但可以“返回”结果集—其实就是select语句执行后显示结果集
定义形式:
其中,In, out, inout用于修饰一个形参的“数据流向”:
- In:只作为外部输入数据,调用环境传入存储过程内部,默认值。
- Out:只作为输出数据,即存储过程传出调用环境
- Inout:具有双重
存储过程调用形式:
Call 存储过程名(实参1,实参2, ……);
举例:
注:实际在php中是这样:
$sql = “call pro1(8, ‘dd’)”;
Mysql_query($sql);
- 删除:drop procedre [if exists] 存储过程名;
触发器:
触发器介绍
就是mysql中的一种“一触即发”的机器(机制):其实只是预先设置的一段代码,改代码无需人为调用,在“预计”的某种情形下会自动执行
通常就这几个情形:对某个数据表的增(或删或改)之前(或之后) //可见只有6种情形
触发器内部也跟存储过程或存储函数一样,属于“编程环境”.
定义形式:
语法:
create trigger 触发器名 before (或after) insert(或update或delete) on 表名 for each now
begin
要执行的代码,语句块,编程环境但这里不能使用select语句
end;
在触发器内部,其中有两个关键字具有特定含义和数据获取作用:
New:代表新插入的一条数据,在insert事件的时候有效; Old:代表旧的诗句,在update或delete的时候有效
编程环境总结
- 共同点:
- 可以使用普通变量
- 可以使用流程控制结构;
- 其实都只是“一段代码”而已,存储在数据库中
- 存储函数:
- 需要返回一个数据值;
- 不能有select语句;
- 调用时直接当做一个“数据”来使用,即可以用于select或别的各种数据操作语句中
- 存储过程:
- 不能返回数据
- 可以有select语句
- 形参可以设定为数据的进出方向:in, out, inout
- 调用的使用call语句
- 触发器:
- 不能返回数据;
- 不能有select语句;
- 也没有参数,也不能调用,而是在触发的情况下自动调用