• mysql 复习



    DCL :
    一个项目创建一个用户,一个项目的对应的数据库只有一个
    这个用户只能对这个数据库有权限,其他的数据库你操作不了
    这些操作只有root 用户才有这个本事
    1.创建用户:
    create user '用户名'@'指定的ip地址' identified by '密码';
    ->用户只能在指定的ip地址登录
    create user '用户名'@'%' identified by '密码'
    ->用户只能在任意的ip地址登录

    2.给用户授权:
    grant 权限1,权限2,......权限n on 数据库.数据库对象 to '用户名'@'ip地址';
    ->权限 用户 数据库
    ->给用户分派在制定的数据库上的制定的权限
    grant all on 数据库.* to '用户名'@'ip地址';
    给指定的用户在制定的数据数据库是上所有的权限
    例如:
    grant create,alter,drop,insert,update,delete,select on db3 to '用户名'@'ip地址'
    授完权限刷新权限列表或重启服务器
    flush privileges;(net stop mysql net start mysql)
    3.回收权限:
    revoke 权限1,权限2,......权限n on 数据库.* from '用户名'@'ip地址';
    4.查看用户权限:
    show grants for '用户名'@'ip地址'
    5.删除用户
    drop user 用户名@ip地址
    6.查看当前登录的用户
    select user();

    DDL:

    查看数据库
    show databases;
    查看表
    show tables;
    查看表结构
    desc 表名;
    查看建表语句
    show create table 表名;
    创建表
    create table if not exists 表名(
    列名 数据类型,
    列名 数据类型,
    。。。。
    列名 数据类型
    );
    create table tb_stu(num char(11),name varchar(50),age int,gender varchar(10));

    修改表:
    1.添加列
    alter table 表名 add (列名 数据类型,列名 数据类型)
    2.修改列类型
    alter table 表名 modify 列名1 列类型 ;
    3.删除一列
    alter table 表名 drop 列名;
    4.修改表名称
    alter table 表名 rename to 新的表名称

    DML:
    插入数据:
    insert into 表名 (列名1 ,类名2......)values(列值1,列值2......);
    修改数据:
    update 表名 set 列名=列值,列名2=列值 where 条件(= != <> > >= < <= is null is not null in() between and
    删除记录:
    delete from 表名 where 条件

    DQL:
    =================员工表建表语句=====================
    CREATE TABLE emp(
    empno INT,
    ename VARCHAR(50),
    job VARCHAR(50),
    mgr INT,
    hiredate DATE,
    sal DECIMAL(7,2),
    comm decimal(7,2),
    deptno INT
    ) ;
    =================员工初始化语句=====================
    INSERT INTO emp values(7839,'如来','董事长',NULL,'1981-11-17',5000,NULL,10);
    INSERT INTO emp values(7782,'玉帝','经理',7839,'1981-06-09',2450,NULL,10);
    INSERT INTO emp values(7934,'王母','职员',7782,'1982-01-23',1300,NULL,10);
    INSERT INTO emp values(7566,'唐僧','经理',7839,'1981-04-02',2975,NULL,20);
    INSERT INTO emp values(7788,'孙悟空','分析师',7566,'1987-04-19',3000,NULL,20);
    INSERT INTO emp values(7876,'猪八戒','文员',7788,'1987-05-23',1100,NULL,20);
    INSERT INTO emp values(7902,'沙僧','分析师',7566,'1981-12-03',3000,NULL,20);
    INSERT INTO emp values(7369,'白龙马','文员',7902,'1980-12-17',800,NULL,20);
    INSERT INTO emp values(7698,'刘备','经理',7839,'1981-05-01',2850,NULL,30);
    INSERT INTO emp values(7499,'关羽','销售员',7698,'1981-02-20',1600,300,30);
    INSERT INTO emp values(7521,'张飞','销售员',7698,'1981-02-22',1250,500,30);
    INSERT INTO emp values(7654,'马超','销售员',7698,'1981-09-28',1250,1400,30);
    INSERT INTO emp values(7900,'赵云','职员',7698,'1981-12-03',950,NULL,30);
    INSERT INTO emp values(7844,'黄忠','销售员',7698,'1981-09-08',1500,0,30);
    ======================部门表建表语句=======================
    CREATE TABLE dept(
    deptno INT,
    dname varchar(14),
    loc varchar(13)
    );
    =======================部门表初始化语句===================
    INSERT INTO dept values(10, '财务部', '北京');
    INSERT INTO dept values(20, '研发部', '上海');
    INSERT INTO dept values(30, '销售部', '广州');
    INSERT INTO dept values(40, '人事', '杭州');

    一 字段(列) 控制
    1.查询所有列 select * from 表名
    2.查询制定列 select 列1 [,列2,列3,......列n] from 表名
    3.完全重复的记录只显示一次 select distinct * |列1 [,列2,列3,......列n] from 表名
    4.列运算
    1>数量类型的列可以做加减乘除运算
    select *,sal from emp;
    select *,sal*1.5 from emp;
    select *,ename*1.5 from emp;
    2>字符串类型的可以做连接运算: concat('要连接的串1',字段1,'要连接的串2',字段2,.....)
    select ename, concat('$',sal) from emp;
    select concat('我叫',ename,',我的工作是',job) from emp;
    3>转换空值(null)
    select ename,sal+comm from emp;(任何数字和null 运算都得null)
    select *,sal + ifnull(comm,0) from emp;
    select ename .,ifnull(mgr,'boss') from emp;
    4>别名 as 可以省略
    select ename as 姓名,job as 工作 from emp;
    select ename 姓名,job 工作 from emp;

    二、条件控制
    1.条件查询 where 子句
    select * from emp where sal > 2000;
    select * from emp where comm is not null;
    select * from emp where sal between 2000 and 3000;
    select * from emp where job in ('分析师','职员');
    2.模糊查询like _:代表任意一个字符 %:任意0~n个字母
    select * from emp where ename like '孙';
    三、排序
    1.升序 order by asc(asc可以声明省略,默认就是升序)
    select * from emp order by sal asc;
    2.降序 order by desc(desc不可以省略)
    select * from emp order by sal desc;
    3.多列排序
    select * from emp order by sal asc;
    select * from emp order by sal asc ,comm asc,empno desc;
    四、聚合函数(纵向查询)
    1.count --计算不为null的
    select count(*) from emp;--一行上全部为null才算null
    select count(comm) from emp;
    select count(1) from emp;
    select count(200) from emp;
    2.sum--求和
    select sum(sal) from emp;
    select sum(comm) from emp;
    select sum(ename) from emp;
    3.max--最大
    select max(sal) from emp
    4.min --最小
    select min(sal) from emp;
    5.avg --平均
    select avg(sal) from emp;

    五、分组查询(排队,男的一排 女的一排,北京的一组,河北的一组,戴眼镜的一组,不带的分组)group by
    分组查询不能查询个人信息,只能查询组信息
    select job,count(*) from emp ;
    select job,count(*) from emp group by job ;
    select job,count(*),max(sal) from emp group by job ;
    select deptno,count(*) from emp where sal > 1500 group by deptno;--每个部门工资大于1500的人数
    select deptno,count(*) from emp where sal >1500 group by deptno having count(*) > 2
    六、limit 方言
    select * from emp limit 0,5;--从0行开始 查5行记录
    分页:(当前页-1)*每页记录数
    七、sql语句顺序
    select from where group by having order by

    -------------------------------------------------------------
    子查询: 查询中有查询(查看select 关键字的个数)
    位置
    select
    from 子查询位置
    where 子查询位置
    1.出现的位置
    from 后面作为表存在(多行多列)--对结果集进行进一步查询
    where 后面作为条件存在

    2.条件
    (***) 单行单列 : select * from 表名1 别名1 where 列1 [= > < >= <= !=] (select 列 from 表2 别名2 where 条件)
    -- 本公司工资最高人的记录:SELECT * FROM emp WHERE sal = (SELECT MAX(sal) FROM emp)
    -- 查找高于平均工资的所有人:SELECT * FROM emp WHERE sal >= ( SELECT AVG(sal) FROM emp ) ;
    (**) 多行单列 : select * from 表1 别名1 where 列1 [in all any ] (select 列 from 表2 别名2 where 条件)
    -- 查找工资大于30部门的所有工资 :SELECT * FROM emp WHERE sal > ALL( SELECT sal FROM emp WHERE deptno = 30 ) ;
    -- 查找大于20部门的任意人的所有员工:SELECT sal FROM emp WHERE sal > ANY( SELECT sal FROM emp WHERE deptno = 20 ) ;
    (*) 单行多列 : select * from 表1 别名1 where (列1 列2) in (select 列1,列2 from 表2 别名2 where 条件)
    --查询工资和部门与张飞完全相同的员工:SELECT * FROM emp WHERE (sal,deptno) IN (SELECT sal,deptno FROM emp WHERE ename = '张飞');
    (***) 多行多列 :select * from 表1 别名1,(select ...) 别名2 where 条件
    SELECT e.* FROM (SELECT * FROM emp WHERE deptno = 10) e

    连接查询
    内连接
    外连接
    左外连接
    右外连接
    全外连接(mysql不支持)
    自然连接
    select * from emp,dept;--笛卡尔积
    内连接: 内连接查询出的所有记录都符合条件
    方言:select * from 表名1 别名1 ,表名2 别名2 where 别名1.xx = 别名2.xx
    标准 : select * from 表名1 别名1 inner join 表名2 别名2 on 别名1.xx = 别名2.xx

    外连接

    左外:select * from 表1 别名1 left outer join 表2 别名2 on 别名1.xx = 别名2.xx
    --> 左表的记录无论是否满足条件都会查询出来,右边只有满足条件的才查询出来,左表
    不满足条件的记录,右表部分都为null
    左外自然:select * from 表1 别名1 natural left outer join 表2 别名2

    右外:select * from 表1 别名1 right outer join 表2 别名2 on 别名1.xx = 别名2.xx
    右表记录无论是否满足条件都会查询出来,而左表只有满足条件的才查询出来,右表不满足
    条件的记录,其左表部分都为空
    右外自然:select * from 表1 别名1 natural right outer join 表2 别名2


    --------------------------------------------------------------------------
    约束
    约束是添加到列上的,用来约束列的

    1.主键约束(唯一标识)
    主键的特点:
    非空
    唯一
    可被引用(外键引用主键)

    当表的某一列被指定为主键后,该列就不能为空,并且不能有重复的值出现

    创建表时指定主键的两种方式:
    方式一:
    create table stu(
    sid char(6) primary key,--指定sid列为主键列,既sid 列添加主键约束
    sname varchar(20),
    age int,
    gender varchar(10)
    );

    方式二:
    create table stu(
    sid char(6) primary key,
    sname varchar(20),
    age int,
    gender varchar(10),
    primary key(sid)--指定sid为主键列
    );

    修改主键:
    alter table stu add primary key(sid);

    删除主键:
    alter table stu drop primary key;
    -------------------------------------------------------
    主键自增长:
    因为主键的特性是:必须唯一,不能为空,所以我们通常会制定
    主键的类型为整型,然后设置其自动增长,这样可以保证在插入
    数据的时候主键的唯一和非空特性

    方式一:
    创建表的时候指定主键自增长
    create table stu(
    sid int primary key auto_increment,
    sname varchar(20),
    age int,
    gender varchar(10)
    );

    修改主键自增长:
    alter table stu change sid sid int auto_increment;
    删除主键自增长
    alter table stu change sid sid int;

    测试主键自增长:
    insert into stu values(null,'zs',23,'m');
    insert into stu(sname,age,gender) values (null,'zs',23,'m');


    -----------------------------------------
    非空约束;
    因为某些列不能设置为空值,所以就可对这列添加非空约束
    例如:
    create table stu(
    sid int primary key auto_increment,
    sname varchar(20) not null,
    age int,
    gender varchar(10)
    );

    唯一约束:
    数据库某些列不能设置重复的值,所以可以对其添加唯一约束
    例如:
    create table stu(
    sid int primary key auto_increment,
    sname varchar(20) not null unique,--对sname 设置了非空并且唯一约束
    age int,
    gender varchar(10)
    );

    -----------------------------------------------------

    ------------------------------------------------------事务---------------------------------------------------
    1.事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行
    事务是一个不可分割的工作逻辑单元
    2.在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
    3. 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
    4. 事务用来管理 insert,update,delete 语句
    5.事务是必须满足4个条件(ACID): Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
    原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行
    一致性(Consistency):当事务完成时,数据必须处于一致状态
    隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响 其他事务
    永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性
    6.查看事务是否自动提交 show variables like 'autocommit';
    7.设置事务自动提交 set autocommit = 0(禁止自动提交)/1(自动提交)
    8.开启事务 BEGIN或START TRANSACTION
    9.提交事务 commit
    10.回滚事务 rollback/ROLLBACK TO identifier 把事务回滚到标记点;
    11.设置保存点 SAVEPOINT identifier

    12.MYSQL 事务处理主要有两种方法:

    1)、用 BEGIN, ROLLBACK, COMMIT来实现
    BEGIN 开始一个事务
    ROLLBACK 事务回滚
    COMMIT事务确认

    2)、直接用 SET 来改变 MySQL 的自动提交模式:
    SET AUTOCOMMIT=0禁止自动提交
    SET AUTOCOMMIT=1 开启自动提交

    举例:
    SET AUTOCOMMIT = 0; -- 禁止自动提交
    BEGIN;
    SAVEPOINT point1;
    INSERT INTO person VALUES (NULL,'牛犇');
    SAVEPOINT point2;
    INSERT INTO person VALUES (NULL,'牛犇犇');
    SAVEPOINT point3;
    INSERT INTO person VALUES (NULL,'牛犇犇犇');
    ROLLBACK TO point2;;
    COMMIT;
    ------------------------------------------------------视图----------------------------------------------------

    视图:是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成
    1.对于复杂的查询事件,每次查询都需要编写MySQL代码效率低下。为了解决这个问题,数据库提供了视图(view)功能。
    2.视图是虚拟表,本身不存储数据,而是按照指定的方式进行查询。
    3.视图只是一个查询语句,单表视图可以修改数据,跨表的视图不可以

    创建视图:
    语法:
    CREATE OR REPLACE VIEW 视图名(列1,列2...)
    AS SELECT (列1,列2...)
    FROM ...;

    修改视图:
    语法:
    alter view 视图名 as select 语句;

    应用视图:
    1)单表视图--增删改查
    2)多表视图--只能查询

    查看视图:
    show tables;

    删除视图
    drop view 视图名称

    查看视图结构
    desc 视图名称


    --------------------------------------------------------索引--------------------------------------------------
    MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
    打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。
    索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
    创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
    实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
    上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
    建立索引会占用磁盘空间的索引文件。
    普通索引 :
    创建索引
    这是最基本的索引,它没有任何限制。它有以下几种创建方式:
    CREATE INDEX indexName ON mytable(username(length));
    如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定 length。
    修改表结构(添加索引)
    ALTER table tableName ADD INDEX indexName(columnName)
    创建表的时候直接指定
    CREATE TABLE mytable(
    ID INT NOT NULL,
    username VARCHAR(16) NOT NULL,
    INDEX [indexName] (username(length))
    );
    删除索引的语法
    DROP INDEX [indexName] ON mytable;

    CREATE INDEX i_p ON person(pname);

    DROP INDEX i_p ON person;

    ALTER TABLE person ADD INDEX i_p ON (pname);
    ALTER TABLE person ADD INDEX i_p ON (pname(50))

    CREATE TABLE person1(
    pid INT ,
    pname VARCHAR(30),
    INDEX ind_p (pname)
    );

    DROP INDEX ind_p ON person1;

    CREATE UNIQUE INDEX ind_p ON person1(pname) ;
    --------------------------------------------------------------------------------
    唯一索引
    它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
    创建索引
    CREATE UNIQUE INDEX indexName ON mytable(username(length))
    修改表结构
    ALTER table mytable ADD UNIQUE [indexName] (username(length))
    创建表的时候直接指定
    CREATE TABLE mytable(
    ID INT NOT NULL,
    username VARCHAR(16) NOT NULL,
    UNIQUE [indexName] (username(length))
    );
    --------------------------------------------------------------------------------
    使用ALTER 命令添加和删除索引
    有四种方式来添加数据表的索引:
    ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
    ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
    ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
    ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为 FULLTEXT ,用于全文索引。
    以下实例为在表中添加索引。
    mysql> ALTER TABLE testalter_tbl ADD INDEX (c);
    你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引:
    mysql> ALTER TABLE testalter_tbl DROP INDEX c;
    --------------------------------------------------------------------------------
    使用 ALTER 命令添加和删除主键
    主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:
    mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
    mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);
    你也可以使用 ALTER 命令删除主键:
    mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;
    删除主键时只需指定PRIMARY KEY,但在删除索引时,你必须知道索引名。
    --------------------------------------------------------------------------------
    显示索引信息
    使用 SHOW INDEX 命令来列出表中的相关的索引信息。可以通过添加 G 来格式化输出信息。
    尝试以下实例:
    mysql> SHOW INDEX FROM table_name; G

    mysql数据库引擎:
    - innodb 支持事务,有行级锁,
    适合更新较多场景
    - myisam 不支持事务,只有表级锁,
    适合更新较少,查询较多场景适合更新较少,查询较多场景
    ........
    ~~~~~~~~~~~~~~~~~~~~~~~~变量~~~~~~~~~~~~~~~~~~~~~~~~
    一、局部变量
    1.局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句块执行完毕后,局部变量就消失了
    例如:下面存储过程中定义的变量c就是局部变量
    --删除存储过程
    DROP PROCEDURE IF EXISTS proc_1;
    -- 定义存储过程
    DELIMITER //
    CREATE PROCEDURE proc_1(IN a INT,IN b INT)
    BEGIN
    DECLARE c INT DEFAULT 5;
    SET c = a + b;
    SELECT c;
    END//
    DELIMITER ;
    -- 调用存储过程
    CALL proc_1(3,5);

    二、用户变量。
    1.用户变量的作用域要比局部变量要广。用户变量可以作用于当前整个连接,但是当当前连接断开后,其所定义的用户变量都会消失。
    2.用户变量使用如下的方式定义:@变量名
    3.对用户变量赋值有两种方式,一种是直接用"="号,另一种是用":="号。其区别在于使用set命令对用户变量进行赋值时,两种方式都可以使用;当使用select语句对用户变量进行赋值时,只能使用":="方式,因为在select语句中,"="号被看作是比较操作符。
    区别:
    set 用于普通的赋值
    select用于从表中查询数据并赋值,必须保证筛选的记录只有1条,否则取最后一条,可演示证明

    例如1: 下面的例子中@result 就是用户变量
    DROP PROCEDURE IF EXISTS mymath;

    DELIMITER //
    CREATE PROCEDURE mymath(IN a INT,IN b INT)
    BEGIN
    SET @result = 0;
    SELECT @result := a + b;
    END//
    DELIMITER ;

    CALL mymath(3,5);

    例如2:
    SET @mysum = (SELECT COUNT(*) FROM emp);
    SELECT @mysum_1 := (SELECT COUNT(*) FROM emp);

    三、系统变量 mysql一启动的时候就会读取系统变量(这样做目的是可以确定mysql的以何种机制或模式运行),
    MySQL用 "set @@系统变量"的形式去改变系统变量的值,但是不涉及定义系统变量(也就是说系统的变量只能读取或改变不能定义)
    1.查看系统变量
    show variables ;
    例如:SHOW VARIABLES LIKE 'char%'; 查看系统的字符集
    SHOW VARIABLES LIKE 'auto%'; 查看是否自动提交
    2.设置系统变量
    例如:
    Set @@character_set_client=gbk;
    set @@autocommit = 0;
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


    ~~~~~~~~~~~~~~~~~~~~~~~~存储过程~~~~~~~~~~~~~~~~~~~~~~~~
    1.简介:(MySQL在5.0之后支持存储过程)我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
    2.存储过程可以包含数据操纵语句、变量、逻辑 控制语句等
    3.存储过程通常有以下优点:
    (1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
    (2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业 人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
    (3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速 度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计 划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
    (4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存 储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。
    (5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制 ,避免了非授权用户对数据的访问,保证了数据的安全。

    4.格式
    CREATE PROCEDURE 存储过程名 ([过程参数[,...]])
    [特性 ...] 过程体
    例如:
    -- 定义用户变量
    SET @s = 0;
    -- 创建存储过程
    DELIMITER //
    CREATE PROCEDURE proc_2(OUT s INT)
    BEGIN
    SELECT COUNT(*) INTO s FROM emp;
    END
    //
    DELIMITER ;

    -- 调用存储过
    CALL proc_2(@s);
    -- 答应结果
    SELECT @s;

    5、DELIMITER:
    DELIMITER //和DELIMITER ;两句,DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。
    6.过程参数:
    1)IN 输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
    -- 定义用户变量
    SET @p_in = 2;
    -- 创建存储过程
    DELIMITER //
    CREATE PROCEDURE proc_3(IN p INT)
    BEGIN
    SET p = 999;
    END
    //
    DELIMITER ;
    -- 调用存储过程
    CALL proc_3(@p_in);
    -- 打印结果
    SELECT @p_in;
    2)OUT 输出参数:该值可在存储过程内部被改变,并可返回
    例如:
    -- 设置用户变量
    SET @p_out=1;
    -- 创建储存过程
    DELIMITER //
    CREATE PROCEDURE proc_3(OUT p_out INT)
    BEGIN
    SELECT p_out;
    SET p_out=2;
    SELECT p_out;
    END;
    //
    DELIMITER ;
    -- 调用存储过程
    CALL proc_3(@p_out);
    -- 打印结果
    SELECT @p_out;


    INOUT 输入输出参数:调用时指定,并且可被改变和返回
    -- 设置用户变量
    SET @p_in_out=1;
    -- 创建储存过程
    DELIMITER //
    CREATE PROCEDURE proc_4(INOUT p_in_out INT)
    BEGIN
    SELECT p_in_out;
    SET p_in_out=2;
    SELECT p_in_out;
    END;
    //
    DELIMITER ;
    -- 调用存储过程
    CALL proc_4(@p_in_out);
    -- 打印结果
    SELECT @p_in_out;
    7.begin -- end :
    过程体的开始与结束使用BEGIN与END进行标识。
    8.定义变量:
    DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
    例如:
    DECLARE l_int int unsigned default 4000000;
    DECLARE l_numeric number(8,2) DEFAULT 9.95;
    DECLARE l_date date DEFAULT '1999-12-31';
    DECLARE l_datetime datetime DEFAULT '1999-12-31 23:59:59';
    DECLARE l_varchar varchar(255) DEFAULT 'This will not be padded';
    9.局部变量赋值
    SET 变量名 = 值
    例如:
    SELECT 'Hello World' INTO @X;
    SELECT @X;
    或者
    SET @Y='Goodbye Cruel World';
    SELECT @Y;
    10.调用:call 存储过程名(参数列表)
    用call和过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。
    11.查看所有存储过程(root用户)
    -- root 用户
    SELECT * FROM mysql.proc WHERE db='bwdb';
    12.删除存储过程:DROP PROCEDURE 存储过程名;

    13.条件语句 --if-then -else

    DELIMITER //
    CREATE PROCEDURE proc_getGrade_1(IN stu_grade INT)
    BEGIN
    IF stu_grade>=90 THEN
    SELECT 'A';
    ELSEIF stu_grade<90 AND stu_grade>=80 THEN
    SELECT 'B';
    ELSEIF stu_grade<80 AND stu_grade>=70 THEN
    SELECT 'C';
    ELSEIF stu_grade70 AND stu_grade>=60 THEN
    SELECT 'D';
    ELSE
    SELECT 'E';
    END IF;
    END;
    //
    DELIMITER ;

    CALL proc_getGrade(91);

    14、循环语句 -- while
    DELIMITER //
    CREATE PROCEDURE proc_6()
    BEGIN
    DECLARE var INT;
    SET var=0;
    WHILE var<6 DO
    INSERT INTO t1 VALUES(NULL,var);
    SET var=var+1;
    END WHILE;
    END;
    //
    DELIMITER ;

    CALL proc_6();
    ~~~~~~~~~~~~~~~~~~~~~~~~~触发器~~~~~~~~~~~~~~~~~~~~~~~
    1.触发器(trigger):监视某种情况,并触发某种操作。
    2.特点
    1)是个特殊的存储过程
    2)它的执行不是由程序调用,也不是手工启动,而是由事件来触发。 insert,delete, update)
    3)触发器经常用于加强数据的完整性约束和业务规则等。
    3.为什么要使用触发器?
    1)可以使用它来检查或预防坏的数据进入数据库。
    2)可以改变或取消INSERT、UPDATE、以及DELETE语句。
    3)可以在一个会话中监视数据改变的动作。
    4.触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/before) 4.触发事件(insert/update/delete)

    5.语法:
    create trigger 触发器名称
    after/before insert/update/delete
    on 表名
    for each row #这句话在mysql是固定的
    begin
    sql语句;
    end;

    6.例子
    #商品表
    create table g
    (
      id int primary key auto_increment,
      name varchar(20),
      num int
    );

    #订单表
    create table o
    (
      oid int primary key auto_increment,
      gid int,
    much int
    );
    insert into g(name,num) values('商品1',10),('商品2',10),('商品3',10);
    如果我们在没使用触发器之前:假设我们现在卖了3个商品1,我们需要做两件事
    1.往订单表插入一条记录
    insert into o(gid,much) values(1,3);
    2.更新商品表商品1的剩余数量
    update g set num=num-3 where id=1;
    现在,我们来创建一个触发器:
    需要先执行该语句:delimiter $(意思是告诉mysql语句的结尾换成以$结束)
    create trigger tg1
    after insert on o
    for each row
    begin
    update g set num=num-3 where id=1;
    end$
    这时候我们只要执行:
    insert into o(gid,much) values(1,3)$
    会发现商品1的数量变为7了,说明在我们插入一条订单的时候,触发器自动帮我们做了更新操作。
    但现在会有一个问题,因为我们触发器里面num和id都是写死的,所以不管我们买哪个商品,最终更新的都是商品1的数量。

    比如:我们往订单表再插入一条记录:insert into o(gid,much) values(2,3),执行完后会发现商品1的数量变4了,

    而商品2的数量没变,这样显然不是我们想要的结果。我们需要改改我们之前创建的触发器。
    我们如何在触发器引用行的值,也就是说我们要得到我们新插入的订单记录中的gid或much的值。
    对于insert而言,新插入的行用new来表示,行中的每一列的值用new.列名来表示。
    所以现在我们可以这样来改我们的触发器
    create trigger tg2
    after insert on o
    for each row
    begin
    update g set num=num-new.much where id=new.gid;(注意此处和第一个触发器的不同)
    end$
    第二个触发器创建完毕,我们先把第一个触发器删掉
    drop trigger tg1$
    再来测试一下,插入一条订单记录:insert into o(gid,much) values(2,3)$
    执行完发现商品2的数量变为7了,现在就对了。
    现在还存在两种情况:
    1.当用户撤销一个订单的时候,我们这边直接删除一个订单,我们是不是需要把对应的商品数量再加回去呢?
    2.当用户修改一个订单的数量时,我们触发器修改怎么写?
    我们先分析一下第一种情况:
    监视地点:o表
    监视事件:delete
    触发时间:after
    触发事件:update
    对于delete而言:原本有一行,后来被删除,想引用被删除的这一行,用old来表示,old.列名可以引用被删除的行的值。
    那我们的触发器就该这样写:
    create trigger tg3
    after delete on o
    for each row
    begin
    update g set num = num + old.much where id = old.gid;(注意这边的变化)
    end$
    创建完毕。
    再执行delete from o where oid = 2$
    会发现商品2的数量又变为10了。
    第二种情况:
    监视地点:o表
    监视事件:update
    触发时间:after
    触发事件:update
    对于update而言:被修改的行,修改前的数据,用old来表示,old.列名引用被修改之前行中的值;
    修改的后的数据,用new来表示,new.列名引用被修改之后行中的值。
    那我们的触发器就该这样写:
    create trigger tg4
    after update on o
    for each row
    begin
    update g set num = num+old.much-new.much where id = old/new.gid;
    end$
    先把旧的数量恢复再减去新的数量就是修改后的数量了。
    我们来测试下:先把商品表和订单表的数据都清掉,易于测试。
    假设我们往商品表插入三个商品,数量都是10,
    买3个商品1:insert into o(gid,much) values(1,3)$
    这时候商品1的数量变为7;
    我们再修改插入的订单记录: update o set much = 5 where oid = 1$
    我们变为买5个商品1,这时候再查询商品表就会发现商品1的数量只剩5了,说明我们的触发器发挥作用了。

    ----------------------------数据库的备份和恢复---------------------------------------------------
    数据的恢复和备份: 数据库 --> 脚本文件(备份) 脚本文件-->数据库(恢复)
    1.数据库导成sql脚本
    mysqldump -u用户名 -p密码 数据库名 > 生成的文价脚本路径
    例如:mysqldump -uroot -p123 bwdb >c:wdb.sql
    注意:mysqldump 是一个可执行文件
    1.不要打分好,不要登录mysql,直接在cmd下运行
    2.生成的脚本文件不包含create database语句
    2.执行脚本文件
    方式一:
    mysql -u用户名 -p密码 数据库<脚本文件路径
    例如:先删除bwdb 库 再重新创建bwdb
    mysql -uroot -p123 bwdb<c:/bwdb.sql
    注意:不打分号,不要登录mysql,直接在cmd下运行
    方式二:
    登录mysql
    用source 命令 执行脚本文件
    例如:
    先删除bwdb库 在重新创建bwdb库
    切换到bwdb库
    source c:wdb.sql

    ----------------------------------------------------------------------------------------------



  • 相关阅读:
    Hadoop无法访问web50070端口
    Hadoop问题汇总
    Hadoop问题汇总
    Linux网络连接模式以及修改静态IP
    Linux网络连接模式以及修改静态IP
    Linux基本命令
    SQLite数据操作
    SQLite初试
    编码与解码
    属性列表
  • 原文地址:https://www.cnblogs.com/JBLi/p/12753074.html
Copyright © 2020-2023  润新知