超详细!SQL语法速成就靠这篇了!(下)

SQL语句
386
0
0
2022-04-01

静默虚空 | 作者

掘金 | 来源

7.数据定义

DDL 的主要功能是定义数据库对象(如:数据库、数据表、视图、索引等)。

1.数据库(DATABASE)

创建数据库

CREATE DATABASE test;

删除数据库

DROP DATABASE test;

选择数据库

USE test;

2.数据表(TABLE)

创建数据表

普通创建

CREATE TABLE user
(  id int(10) unsigned NOT NULL COMMENT 'Id', 
  username varchar(64) NOT NULL DEFAULT 'default' COMMENT '用户名',  
  password varchar(64) NOT NULL DEFAULT 'default' COMMENT '密码', 
  email varchar(64) NOT NULL DEFAULT 'default' COMMENT '邮箱') 
  COMMENT='用户表';

根据已有的表创建新表

CREATE TABLE vip_user AS
SELECT * FROM user;

删除数据表

DROP TABLE user;

修改数据表

添加列

ALTER TABLE user
ADD age int(3);

删除列

ALTER TABLE user
DROP COLUMN age;

修改列

ALTER TABLE `user`
MODIFY COLUMN age tinyint;

添加主键

ALTER TABLE user
ADD PRIMARY KEY (id);

删除主键

ALTER TABLE user
DROP PRIMARY KEY;

视图(VIEW)

定义

  • 视图是基于 SQL 语句的结果集的可视化的表
  • 视图是虚拟的表,本身不包含数据,也就不能对其进行索引操作。对视图的操作和对普通表的操作一样

作用

  • 简化复杂的 SQL 操作,比如复杂的联结
  • 只使用实际表的一部分数据
  • 通过只给用户访问视图的权限,保证数据的安全性
  • 更改数据格式和表示

创建视图

CREATE VIEW top_10_user_view AS
SELECT id, username
FROM user
WHERE id < 10;

删除视图

DROP VIEW top_10_user_view;

索引(INDEX)

作用

  • 通过索引可以更加快速高效地查询数据
  • 用户无法看到索引,它们只能被用来加速查询

注意

  • 更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引

唯一索引

  • 唯一索引表明此索引的每一个索引值只对应唯一的数据记录

创建索引

CREATE INDEX user_index
ON user (id);

创建唯一索引

CREATE UNIQUE INDEX user_index
ON user (id);

删除索引

ALTER TABLE user
DROP INDEX user_index;

约束

SQL 约束用于规定表中的数据规则。

  • 如果存在违反约束的数据行为,行为会被约束终止
  • 约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)

约束类型

  • NOT NULL:指示某列不能存储 NULL 值
  • UNIQUE:保证某列的每行必须有唯一的值
  • PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录
  • FOREIGN KEY:保证一个表中的数据匹配另一个表中的值的参照完整性
  • CHECK:保证列中的值符合指定的条件
  • DEFAULT:规定没有给列赋值时的默认值

创建表时使用约束条件:

CREATE TABLE Users (  
  d INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增Id',  Username VARCHAR(64) NOT NULL UNIQUE DEFAULT 'default' COMMENT '用户名',  Password VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '密码',  Email VARCHAR(64) NOT NULL DEFAULT 'default' COMMENT '邮箱地址',  Enabled TINYINT(4) DEFAULT NULL COMMENT '是否有效',  PRIMARY KEY (Id)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

(以下为 TCL 语句用法)

8.事务处理

  • 不能回退 SELECT 语句,回退 SELECT 语句也没意义;也不能回退 CREATE 和 DROP 语句
  • MySQL 默认是隐式提交,每执行一条语句就把这条语句当成一个事务然后进行提交。当出现 START TRANSACTION 语句时,会关闭隐式提交;当 COMMIT 或 ROLLBACK 语句执行后,事务会自动关闭,重新恢复隐式提交
  • 通过 set autocommit=0 可以取消自动提交,直到 set autocommit=1 才会提交;autocommit 标记是针对每个连接而不是针对服务器的

指令:

  • START TRANSACTION:指令用于标记事务的起始点
  • SAVEPOINT:指令用于创建保留点
  • ROLLBACK TO:指令用于回滚到指定的保留点;如果没有设置保留点,则回退到 START TRANSACTION 语句处
  • COMMIT:提交事务
-- 开始事务
START TRANSACTION;

-- 插入操作 A
INSERT INTO `user`VALUES (1, 'root1', 'root1', 'xxxx@163.com');

-- 创建保留点 updateA
SAVEPOINT updateA;

-- 插入操作B
BINSERT INTO `user`
VALUES (2, 'root2', 'root2', 'xxxx@163.com');

-- 回滚到保留点
updateAROLLBACK TO updateA;

-- 提交事务,只有操作 A 生效
COMMIT;

(以下为 DCL 语句用法)

9.权限控制

GRANT 和 REVOKE 可在几个层次上控制访问权限:

  • 整个服务器,使用 GRANT ALL 和 REVOKE ALL
  • 整个数据库,使用 ON database.*
  • 特定的表,使用 ON database.table
  • 特定的列
  • 特定的存储过程
  • 新创建的账户没有任何权限
  • 账户用 username@host 的形式定义,username@% 使用的是默认主机名
  • MySQL 的账户信息保存在 mysql 这个数据库中
USE mysql;
SELECT user FROM user;
复制代码

创建账户

CREATE USER myuser IDENTIFIED BY 'mypassword';

修改账户名

UPDATE user SET user='newuser' WHERE user='myuser';
FLUSH PRIVILEGES;

删除账户

DROP USER myuser;

查看权限

SHOW GRANTS FOR myuser;

授予权限

GRANT SELECT, INSERT ON *.* TO myuser;

删除权限

REVOKE SELECT, INSERT ON *.* FROM myuser;

更改密码

SET PASSWORD FOR myuser = 'mypass';

10.存储控制

  • 存储过程可以看成是对一系列 SQL 操作的批处理

使用存储过程的好处

  • 代码封装,保证了一定的安全性
  • 代码复用
  • 由于是预先编译,因此具有很高的性能

创建存储过程

  • 命令行中创建存储过程需要自定义分隔符,因为命令行是以 ; 为结束符,而存储过程中也包含了分号,因此会错误把这部分分号当成是结束符,造成语法错误
  • 包含 in、out 和 inout 三种参数
  • 给变量赋值都需要用 select into 语句
  • 每次只能给一个变量赋值,不支持集合的操作

创建存储过程

DROP PROCEDURE IF EXISTS `proc_adder`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_adder`(IN a int, IN b int, OUT sum int)
BEGIN    
DECLARE c int; 
if a is null then set a = 0;
end if;
if b is null then set b = 0;
end if;
set sum  = a + b;
END;;
DELIMITER ;

使用存储过程

set @b=5;
call proc_adder(2,@b,@s);
select @s as sum;

11.游标

  • 游标(cursor)是一个存储在 DBMS 服务器上的数据库查询,它不是一条 SELECT 语句,而是被该语句检索出来的结果集
  • 在存储过程中使用游标可以对一个结果集进行移动遍历
  • 游标主要用于交互式应用,其中用户需要对数据集中的任意行进行浏览和修改

使用游标的四个步骤:

  • 声明游标,这个过程没有实际检索出数据
  • 打开游标
  • 取出数据
  • 关闭游标
DELIMITER $
CREATE  PROCEDURE getTotal()
BEGIN    
DECLARE total INT;   
-- 创建接收游标数据的变量   
DECLARE sid INT;   
DECLARE sname VARCHAR(10);   
-- 创建总数变量   
DECLARE sage INT;   
-- 创建结束标志变量    
DECLARE done INT DEFAULT false;  
-- 创建游标    
DECLARE cur CURSOR FOR SELECT id,name,age from cursor_table where age>30;  
-- 指定游标循环结束时的返回值    
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;    
SET total = 0;  
OPEN cur;   
FETCH cur INTO sid, sname, sage;   
WHILE(NOT done)    DO      
SET total = total + 1;    
FETCH cur INTO sid, sname, sage;  
END WHILE;
CLOSE cur;    
SELECT total;
END $
DELIMITER ;
- 调用存储过程
call getTotal();

12.触发器

触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。

可以使用触发器来进行审计跟踪,把修改记录到另外一张表中。

MySQL 不允许在触发器中使用 CALL 语句 ,也就是不能调用存储过程。

1.BEGIN 和 END

当触发器的触发条件满足时,将会执行 BEGIN 和 END 之间的触发器执行动作。

注意:在 MySQL 中,分号 ; 是语句结束的标识符,遇到分号表示该段语句已经结束,MySQL 可以开始执行了。因此,解释器遇到触发器执行动作中的分号后就开始执行,然后会报错,因为没有找到和 BEGIN 匹配的 END。

这时就会用到 DELIMITER 命令(DELIMITER 是定界符,分隔符的意思)。它是一条命令,不需要语句结束标识,语法为:DELIMITER new_delemiter。new_delemiter 可以设为 1 个或多个长度的符号,默认的是分号 ;,我们可以把它修改为其他符号,如 $ - DELIMITER $ 。在这之后的语句,以分号结束,解释器不会有什么反应,只有遇到了 $,才认为是语句结束。注意,使用完之后,我们还应该记得把它给修改回来。

2.NEW 和 OLD

  • MySQL 中定义了 NEW 和 OLD 关键字,用来表示触发器的所在表中,触发了触发器的那一行数据
  • 在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据
  • 在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据
  • 在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据
  • 使用方法:NEW.columnName (columnName 为相应数据表某一列名

3.创建触发器

提示:为了理解触发器的要点,有必要先了解一下创建触发器的指令。

CREATE TRIGGER 指令用于创建触发器。

语法:

CREATE TRIGGER trigger_name
trigger_time
trigger_event
ON table_name
FOR EACH ROW
BEGIN  
trigger_statements
END;

说明:

  • trigger_name:触发器名
  • trigger_time: 触发器的触发时机。取值为 BEFORE 或 AFTER
  • trigger_event: 触发器的监听事件。取值为 INSERT、UPDATE 或 DELETE
  • table_name:触发器的监听目标。指定在哪张表上建立触发器
  • FOR EACH ROW: 行级监视,Mysql 固定写法,其他 DBMS 不同
  • trigger_statements: 触发器执行动作。是一条或多条 SQL 语句的列表,列表内的每条语句都必须用分号 ; 来结尾

示例:

DELIMITER $
CREATE TRIGGER `trigger_insert_user`
AFTER INSERT ON `user`
FOR EACH ROW
BEGIN    
INSERT INTO `user_history`(user_id, operate_type, operate_time)    
VALUES (NEW.id, 'add a user',  now());
END $
DELIMITER

查看触发器

SHOW TRIGGERS;

删除触发器

DROP TRIGGER IF EXISTS trigger_insert_user;

- END -

本文为转载分享&推荐阅读,若侵权请联系后台删除