主要跟菜鸟MYSQL来整理的,用于学习笔记。
MySql是关系型数据库。
windows环境:
首先以管理员身份运行命令提示符,然后键入
net start 数据库名称
net stop 数据库名称
如果需要添加MySQL用户,只需要在mysql数据库中的user表添加新用户即可。
root@host# mysql -u root -p
Enter password:******
mysql> use mysql;
Database changed
mysql> INSERT INTO user
(host, user, password,
select_priv, insert_priv, update_priv)
VALUES ('localhost', 'david',
PASSWORD('123456'), 'Y', 'Y', 'Y');
Query OK, 1 row affected (0.20 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 1 row affected (0.01 sec)
在添加用户时,用MySQL提供的PASSWORD()
函数来对密码进行加密。
password()加密函数在8.0.11中移除,使用MD5()函数代替。
注意要执行FLUSH PRIVILEGES
语句,这个命令执行后会重新载入授权表。
选择要操作的数据库
语法
mysql> use 数据库l;
例子
mysql> use books;
Database changed
列出MySQL数据库管理系统的数据库列表
语法
mysql> SHOW DATABASES;
例子
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| books |
| house_price_hz |
| information_schema |
| myemployees |
| mysql |
| performance_schema |
| students |
| sys |
| test |
+--------------------+
9 rows in set (0.00 sec)
现实指定数据库所有的表
语法
mysql> SHOW TABLES;
例子
mysql> USE books;
Database changed
mysql> SHOW TABLES;
+-----------------+
| Tables_in_books |
+-----------------+
| author |
| copy |
| copy2 |
| copy3 |
| copy4 |
+-----------------+
5 rows in set (0.00 sec)
显示数据表的属性,属性类型,主键信息,是否为NULL,默认值等其他信息
语法
mysql> SHOW COLUMNS FROM 数据表;
例子
mysql> SHOW COLUMNS FROM author;
显示数据表的详细索引信息,包括PRIMARY KEY(主键)
mysql> SHOW INDEX FROM 数据表;
输出MySQL数据库管理系统的性能及统计信息
语法
SHOW TABLE STATUS LIKE [FROM db_name] [LIKE 'pattern'] \G:
例子
mysql> SHOW TABLE STATUS FROM books; # 显示数据库 books 中所有表的信息
mysql> SHOW TABLE STATUS from books LIKE 'auth%'; # 表名以auth开头的表的信息
mysql> SHOW TABLE STATUS from books LIKE 'auth%'\G; # 加上 \G,查询结果按列打印
语法
登入:
[root@host]# mysql -u root -p
Enter password: ******
退出:
mysql> exit
Bye
语法
CREATE DATABASE 数据库名;
例子
mysql> CREATE DATABASE HK_U;
语法
DROP DATABASE <数据库名>;
例子
mysql> DROP DATABASE HK_U;
MySQL中定义数据字段的类型对数据库的优化是非常重要的。
MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。
MySQL支持所有标准的SQL数字类型。
这些类型包括严格数值数据类型(INTEGR,SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE RRECISION)。
关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。
BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。
作为SQL标准的拓展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。
类型 | 大小 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|---|
TINYINT | 1 byte | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 bytes | (-32 768,32 767) | (0,65 535) | 大整数值 |
MEDIUMINT | 3 bytes | (-8 388 608,8 388 607) | (0,16 777 215) | 大整数值 |
INT或INTEGER | 4 bytes | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整数值 |
BIGINT | 8 bytes | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 极大整数值 |
FLOAT | 4 bytes | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 单精度 浮点数值 |
DOUBLE | 8 bytes | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度 浮点数值 |
DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 | 小数值 |
表示时间值的日期和时间类型位DATETIME、DATA、TIMESTAMP、TIME和YEAR。
每个时间类型有一个有效值范围和一个“零”值,当指定不合法的MySQL不能表示的值时使用“零”值。
TIMESTAMP类型有专有的自动更新特征。
类型 | 大小 ( bytes) | 范围 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和时间值,时间戳 |
字符串类型值CHAR,VARCHAR,BINARY,VARBINARY、BLOB、TEXT、ENUM和SET。
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 |
TINYBLOB | 0-255 bytes | 不超过 255 个字符的二进制字符串 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 |
TEXT | 0-65 535 bytes | 长文本数据 |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
注意:
char(n)和varchar(n)中括号n代表字符的个数,并不代表字节的个数,比如CHAR(30)就是指可以存储30个字符。CHAR和VARCHAR类型类似,但是它们保存和检索的方式不同,它们的最大长度和是否尾部空格被保留等方面也不同,在存储或检索过程中不进行大小写转换。
BINARY 和 VARBINARY 类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值值。
BLOB 是一个二进制大对象,可以容纳可变数量的数据。有 4 种 BLOB 类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它们区别在于可容纳存储范围不同。
有 4 种 TEXT 类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。对应的这 4 种 BLOB 类型,可存储的最大长度不同,可根据实际情况选择。
创建MySQL数据表需要以下三个要素;
语法
CREATE TABLE table_name (column_name column_type);
例子
CREATE TABLE IF NOT EXISTS `CityU` (
`id` INT UNSIGNED AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`loc` VARCHAR(50) NOT NULL,
`data` DATE,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
解析:
通过命令提示符创建表
CREATE TABLE IF NOT EXISTS CityU (
id INT UNSIGNED AUTO_INCREMENT,
title VARCHAR(100) NOT NULL,
loc VARCHAR(50) NOT NULL,
data DATE,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
注意:
区分""
和NULL
:
""
是不占用空间的NULL
其实是占用空间的,所谓NULL
就是什么都没有,但是在物理内存中是占有空间的mysql> select length(NULL), length(''), length('1');
+--------------+------------+-------------+
| length(NULL) | length('') | length('1') |
+--------------+------------+-------------+
| NULL | 0 | 1 |
+--------------+------------+-------------+
1 row in set (0.00 sec)
所以从上面可以看出空值的长度为1,是不占用空间的,而的NULL长度是NULL,其实它是占用空间的,NULL列需要行中的额外空间来记录它们的值是否为NULL。
如果要单纯查NULL值列,则使用 is NULL
去查,单纯去查空值(’’)列,则使用 =''
。
建议查询方式:NULL值查询使用is null/is not null查询,而空值(’’)可以使用=或者!=、<、>等算术运算符。
使用 COUNT(字段) 统计会过滤掉 NULL 值,但是不会过滤掉空值。
说明:IFNULL有两个参数。 如果第一个参数字段不是NULL
,则返回第一个字段的值。 否则,IFNULL
函数返回第二个参数的值(默认值)。
语法
DROP TABLE table_name;
在命令提示窗口中删除数据表
mysql> use my_hk;
Database changed
mysql> drop table CityU;
Query OK, 0 rows affected (0.05 sec)
语法
(1)指定列名,然后对应数值插入
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );
(2)不指定列名,这样就要插入一个完整的数据
INSERT INTO table_name VALUES
( value1, value2,...valueN );
(3)插入多条语句
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value11, value12,...value1N ),
( value21, value22,...value2N ),
...
( valueX1, valueX2,...valueXN )
如果数据是字符串型,必须使用单引号或者双引号,如:“values”。
例子
mysql> use my_hk;
Database changed
mysql> create table CityU(
-> id int not null auto_increment,
-> major varchar(20) not null,
-> loc varchar(30) not null,
-> primary key(id))ENGINE=INNODB DEFAULT CHARSET=UTF8;
Query OK, 0 rows affected, 1 warning (0.03 sec)
mysql> insert into CityU (major, loc) values('math', 'HK');
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+-------+-----+
| id | major | loc |
+----+-------+-----+
| 1 | math | HK |
+----+-------+-----+
1 row in set (0.00 sec)
mysql> insert into CityU values (2, 'Data Science', 'HK');
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
+----+--------------+-----+
2 rows in set (0.00 sec)
mysql> insert into CityU (major, loc) values ('English', 'SZ'), ('CS', 'SZ');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
+----+--------------+-----+
4 rows in set (0.00 sec)
mysql> insert into CityU values (5, 'English', 'GZ'), (6, 'EE', 'GZ');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+--------------+-----+
6 rows in set (0.00 sec)
语法
select column_name_1,column_name_2, .., column_name_n
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
WHERE
语句来设定查询条件;SELECT
命令可以读取一条或多条记录;SELECT
语句会返回所有字段数据;WHERE
来包含任何条件;LIMIT
属性来设定返回的记录数;OFFSET
来指定SELECT
语句开始查询的数据偏移量,more情况下偏移量为0;例子
-- 查看所有房价
mysql> select * from price;
where
子语句-- 查看上城区的房价
mysql> select * from price where district = '上城';
带有LIMIT
子语句
注意的是OFFSET
指的是偏移量,就是从第几行开始取,而LIMIT
表示的是取多少行,注意!!!OFFSET
的起始是从0(零)开始计算的~~
看下面这两个例子就可以明白
如需有条件地从表中选取数据,可将WHERE
子句添加到SELECT
语句中。
语法
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
,
分割,并使用WHERE
来设定查询条件;WHERE
子句中指定任何条件;AND
或者OR
指定一个或多个条件;WHERE
子句也可以运行于SQL
和’DELETE’或者’UPDATE’命令;WHERE
子句类似程序语言中的if
条件,根据MySQL
表中的字段值来读取指定的数据;常用的操作符:
操作符 | 描述 | 实例 |
---|---|---|
= | 等号,检测两个值是否相等,如果相等返回true | (A = B) 返回false。 |
<>, != | 不等于,检测两个值是否相等,如果不相等返回true | (A != B) 返回 true。 |
> | 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true | (A > B) 返回false。 |
< | 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true | (A < B) 返回 true。 |
>= | 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true | (A >= B) 返回false。 |
<= | 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true | (A <= B) 返回 tru |
例子:
mysql> select * from price where district = '西湖';
BINARY 关键字
MySQL的WHERE
子句的字符串是不区分大小写的,可以使用BINARY
关键字来设定WHERE
子句的字符串是区分大小写的。
mysql> select * from price where BINARY web = 'www.hao123.com'
注意:
WHERE
关键字,用于在初始表中筛选,它是一个约束声明,用来约束数据,在返回结果集之前起作用。where
和 group by
查询出来的分组进行过滤,查出满足条件的分组,它是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作。如果需要修改或者更新MySQL中的数据,可以使用SQL UPDATE命令来操作。
语法
UPDATE table_name SET field1=new-value1, field2=new-value2
[WHERE Clause]
WHERE
子句中指定任何条件;UPDATE table_name SET field=REPLACE(field, 'old-string', 'new-string') [WHERE Clause]
例子
mysql> use my_hk;
Database changed
mysql> select * from CityU;
+----+--------------+-----+
| id | major | loc |
+----+--------------+-----+
| 1 | math | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+--------------+-----+
6 rows in set (0.00 sec)
mysql> update CityU set major = 'math|data science' where id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
+----+-------------------+-----+
6 rows in set (0.00 sec)
mysql> insert into CityU values (7, 'EE', 'HZ'), (8, 'EE', 'HK');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE | GZ |
| 7 | EE | HZ |
| 8 | EE | HK |
+----+-------------------+-----+
8 rows in set (0.00 sec)
mysql> update CityU set major = REPLACE(major, 'EE', 'EE + CS');
Query OK, 3 rows affected (0.01 sec)
Rows matched: 8 Changed: 3 Warnings: 0
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 8 | EE + CS | HK |
+----+-------------------+-----+
8 rows in set (0.00 sec)
可以使用SQL的DELETE FROM
命令来删除MySQL
数据表中的记录。
语法
DELETE FROM table_name [WHERE Clause]
WHERE
子句,MySQL表中的所有记录将被删除;WHERE
子句中指定任何条件;例子
mysql> delete from CityU where id = 8;
Query OK, 1 row affected (0.01 sec)
mysql> select * from CityU;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 3 | English | SZ |
| 4 | CS | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+-------------------+-----+
7 rows in set (0.00 sec)
注意:
``
delete
, drop
, truncate
都有删除表的作用,区别在于;
delete
和truncate
仅仅删除表数据,drop
是连表数据和结构一起删除,打个比方,delete
是单杀,truncate
是团灭, drop
是直接把电脑摔了。delete
是 DML 语句,操作完以后如果没有不想提交事务还可以回滚,truncate
和 drop
是 DDL 语句,操作完马上生效,不能回滚,打个比方,delete
是发微信说分手,后悔还可以撤回,truncate
和 drop
是直接扇耳光说滚,不能反悔。drop>truncate>delete
,打个比方,drop
是神舟火箭,truncate
是和谐号动车,delete
是自行车。truncate
语法:
TRUNCATE TABLE table_name;
WHERE
子句中可以使用等号=
来设定获取数据的条件,如 “runoob_author = ‘RUNOOB.COM’”。
但是有时候我们需要获取 runoob_author 字段含有 “COM” 字符的所有记录,这时我们就需要在WHERE
子句中使用 SQL LIKE 子句。
SQL LIKE 子句中使用百分号 %
字符来表示任意字符,类似于UNIX或正则表达式中的星号 *
。如果没有使用百分号 %
, LIKE
子句与等号 =
的效果是一样的。
语法
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
WHERE
子句中指定任何条件;WHERE
子句中使用LIKE
子句;LIKE
子句替换=
;LIKE
通常与%
一同使用,类似于一个元字符的搜索;AND
或者OR
指定一个或多个条件;DELETE
或UPDATE
命令中使用WHERE...LIKE
子句来指定条件。LIKE
匹配/模糊匹配,会与 %
和 _
结合使用。
'%a' //以a结尾的数据
'a%' //以a开头的数据
'%a%' //含有a的数据
'_a_' //三位且中间字母是a的
'_a' //两位且结尾字母是a的
'a_' //两位且开头字母是a的
例子
mysql> select * from CityU where major like 'E%';
+----+---------+-----+
| id | major | loc |
+----+---------+-----+
| 3 | English | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+---------+-----+
4 rows in set (0.00 sec)
MySQL UNION
操作符用于连接两个以上的SELECT
语句的结果组合到一个结果集合中,多个SELECT
语句会删除重复的数据。
语法
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions]
UNION [ALL | DISTINCT]
SELECT expression1, expression2, ... expression_n
FROM tables
[WHERE conditions];
例子
SQL UNION实例
mysql> select major from CityU union select major from CityU;
+-------------------+
| major |
+-------------------+
| math|data science |
| Data Science |
| English |
| CS |
| EE + CS |
+-------------------+
5 rows in set (0.00 sec)
SQL UNION ALL实例
mysql> select major from CityU union all select major from CityU;
+-------------------+
| major |
+-------------------+
| math|data science |
| Data Science |
| English |
| CS |
| English |
| EE + CS |
| EE + CS |
| math|data science |
| Data Science |
| English |
| CS |
| English |
| EE + CS |
| EE + CS |
+-------------------+
14 rows in set (0.00 sec)
带有WHERE的SQL UNION ALL
mysql> select major from CityU where id = 2 union all select major from CityU where id <> 6 order by major;
+-------------------+
| major |
+-------------------+
| CS |
| Data Science |
| Data Science |
| EE + CS |
| English |
| English |
| math|data science |
+-------------------+
7 rows in set (0.00 sec)
如果需要对读取的数据进行排序,就是使用MySQL的ORDER BY
子句来设定你想按哪个字段哪种方式进行排序,然后再返回结果。
语法
SELECT field1, field2,...fieldN FROM table_name1, table_name2...
ORDER BY field1 [ASC [DESC][默认 ASC]], [field2...] [ASC [DESC][默认 ASC]]
ASC
或 DESC
关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。WHERE...LIKE
子句来设置条件。例子
mysql> select * from CityU order by major desc;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 3 | English | SZ |
| 5 | English | GZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 2 | Data Science | HK |
| 4 | CS | SZ |
+----+-------------------+-----+
7 rows in set (0.00 sec)
mysql> select * from CityU order by major;
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 4 | CS | SZ |
| 2 | Data Science | HK |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
| 3 | English | SZ |
| 5 | English | GZ |
| 1 | math|data science | HK |
+----+-------------------+-----+
7 rows in set (0.00 sec)
注意:MySQL 排序我们知道从 MySQL 表中使用 SQL SELECT 语句来读取:MySQL 拼音排序
如果字符集采用的是 gbk
(汉字编码字符集),直接在查询语句后边添加 ORDER BY
:
SELECT *
FROM runoob_tbl
ORDER BY runoob_title;
如果字符集采用的是 utf8
(万国码),需要先对字段进行转码然后排序:
SELECT *
FROM runoob_tbl
ORDER BY CONVERT(runoob_title using gbk);
GROUP BY
语句根据一个列或者多个列对结果进行分组。
在分组的列上,我们可以使用COUNT
, SUM
, AVG
等函数。
语法
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
例子
CREATE TABLE `employee_tbl` (
`id` int(11) NOT NULL,
`name` char(10) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`singin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登录次数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of `employee_tbl`
-- ----------------------------
INSERT INTO `employee_tbl` VALUES ('1', '小明', '2016-04-22 15:25:33', '1'), ('2', '小王', '2016-04-20 15:25:47', '3'), ('3', '小丽', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'), ('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2');
2)查看表
SELECT * FROM employee_tb1;
3)分组操作
SELECT name, COUNT(*) FROM employee_tb1 GROUP BY name;
使用 WITH ROLLUP
WITH ROLLUP
可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…)。
SELECT name, SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------+--------------+
| name | singin_count |
+--------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| NULL | 16 |
+--------+--------------+
4 rows in set (0.00 sec)
其中记录 NULL 表示所有人的登录次数。
我们可以使用 coalesce 来设置一个可以取代 NUll 的名称,coalesce 语法:
select coalesce(a,b,c);
参数说明:如果anull,则选择b;如果bnull,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null(没意义)
mysql> SELECT coalesce(name, '总数'), SUM(singin) as singin_count FROM employee_tbl GROUP BY name WITH ROLLUP;
+--------------------------+--------------+
| coalesce(name, '总数') | singin_count |
+--------------------------+--------------+
| 小丽 | 2 |
| 小明 | 7 |
| 小王 | 7 |
| 总数 | 16 |
+--------------------------+--------------+
4 rows in set (0.01 sec)
JOIN 按照功能大致分为如下三类:
例子:
-- 创建数据表 tcount_tbl
create table if not exists `tcount_tbl`(
`runoob_author` varchar(20) not null,
`runoob_count` int(5) not null
);
-- 创建数据表 runoob_tbl
create table if not exists `runoob_tbl`(
`runoob_id` int not null auto_increment,
`runoob_title` varchar(20) not null,
`runoob_author` varchar(40) not null,
`submission_date` date not null default '2018-08-08',
primary key(`runoob_id`)
)engine=InnoDB charset=utf8;
-- 插入数据
insert into tcount_tbl values('菜鸟教程', 10), ('RUNOOB.COM', 20), ('GooGle', 22);
insert into runoob_tbl (runoob_title, runoob_author, submission_date) values
('学习 PHP', '菜鸟教程', '2017-04-12'), ('学习 MySQL', '菜鸟教程', '2017-04-12'), ('学习 Java', 'RUNOOB.COM', '2015-05-01'), ('学习 Python', 'RUNOOB.COM', '2016-03-06'), ('学习 C', 'FK', '2017-04-05');
-- 查看数据
select * from tcount_tbl;
select * from runoob_tbl;
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-----------+---------------+--------------+
4 rows in set (0.00 sec)
等价的WHERE
语句
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
+-----------+---------------+--------------+
4 rows in set (0.00 sec)
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| 5 | FK | NULL |
+-----------+---------------+--------------+
5 rows in set (0.00 sec)
这里我们就看看出在inner join中没有的FK在这里出现了,这是因为left join都会将左边的表给完全的匹配完,今晚此时右边可能没有对应的记录。
mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-----------+---------------+--------------+
| runoob_id | runoob_author | runoob_count |
+-----------+---------------+--------------+
| 1 | 菜鸟教程 | 10 |
| 2 | 菜鸟教程 | 10 |
| 3 | RUNOOB.COM | 20 |
| 4 | RUNOOB.COM | 20 |
| NULL | NULL | 22 |
+-----------+---------------+--------------+
5 rows in set (0.00 sec)
这个和上面的左连接非常像,只是现在是右连接,所以右边的记录都会全部匹配。
当提供的查询条件字段为 NULL 时,有些命令可能就无法正常工作。
为了处理这种情况,MySQL提供了三大运算符:
关于 NULL 的条件比较运算是比较特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在 MySQL 中,NULL 值与任何其它值的比较(即使是 NULL)永远返回 NULL,即 NULL = NULL 返回 NULL 。
MySQL 中处理 NULL 使用 IS NULL 和 IS NOT NULL 运算符。
mysql> SELECT * from CityU where major IS NOT NULL;
MySQL 同样支持正则表达式的匹配, MySQL中使用 REGEXP
操作符来进行正则表达式匹配。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。 |
. | 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像 ‘[.\n]’ 的模式。 |
[…] | 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^…] | 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
例子
1)查询major中含有C的记录:
mysql> select * from CityU where major REGEXP '.*C.*';
+----+-------------------+-----+
| id | major | loc |
+----+-------------------+-----+
| 1 | math|data science | HK |
| 2 | Data Science | HK |
| 4 | CS | SZ |
| 6 | EE + CS | GZ |
| 7 | EE + CS | HZ |
+----+-------------------+-----+
5 rows in set (0.00 sec)
2)查询major中以C开头的记录:
mysql> select * from CityU where major REGEXP '^C.*';
+----+-------+-----+
| id | major | loc |
+----+-------+-----+
| 4 | CS | SZ |
+----+-------+-----+
1 row in set (0.00 sec)
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
注意:在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。
BEGIN
或 START TRANSACTION
显示地开启一个事务;
COMMIT
也可以使用 COMMIT WORK
,不过二者是等价地。COMMIT
会提交事务,并使已对数据库进行地所有修改称为永久性地;
ROLLBACK
也可以使用ROLLBACK WORK
,不过二者是等价的,回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
SAVEPOINT identifier
,SAVEPOINT
运行在事务中创建一个保存点,一个事务可以有多个SAVEPOINT
;
RELEASE SAVEPOINT identifier
删除一个事务的保存点,当没有指定的保存点时,执行语句会抛出一个异常;
ROLLBACK TO identifier
把事务回滚到标记点;
SET TRANSCATION
用来设置事务的隔离级别,InnoDB
存储引擎提供事务的隔离级别有READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
和 SERIALIZABLE
。
(1)用BEGIN、ROLLBACK、COMMIT来实现
(2)直接用SET 来改变MySQL的自动提交模式
例子
mysql> create table test_transcation(
-> id int(5)
-> )engine=innodb;
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> select * from test_transcation;
Empty set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_transcation value(5);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_transcation value(6);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from test_transcation;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_transcation value(7);
Query OK, 1 row affected (0.00 sec)
-- 事务回滚
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test_transcation;
+------+
| id |
+------+
| 5 |
| 6 |
+------+
2 rows in set (0.00 sec)
用来修改数据表名或者数据表字段。
mysql> ALTER TABLE 表名 DROP [COLUMN] 列名;
如果同时删除多个列:
mysql> ALTER TABLE 表名 DROP [COLUMN] 列名1,
DROP [COLUMN] 列名2,
...;
注意;
从表中删除列会使所有数据库对象(如存储过程,视图,触发器等)依赖于列无效。 例如,您可能有一个引用列的存储过程。 删除列时,存储过程将变为无效。 要修复它,必须手动更改存储过程的代码。
取决于已删除列的其他应用程序的代码也必须更改,这需要时间和精力。
从大型表中删除列可能会影响数据库的性能。
例子:
mysql> select * from employee_tb1;
+----+------+---------------------+--------+
| id | name | data | singin |
+----+------+---------------------+--------+
| 1 | 小明 | 2016-04-22 15:25:33 | 1 |
| 2 | 小王 | 2016-04-20 15:25:47 | 3 |
| 3 | 小丽 | 2016-04-19 15:26:02 | 2 |
| 4 | 小王 | 2016-04-07 15:26:14 | 4 |
| 5 | 小明 | 2016-04-11 15:26:40 | 4 |
| 6 | 小明 | 2016-04-04 15:26:54 | 2 |
+----+------+---------------------+--------+
6 rows in set (0.00 sec)
mysql> alter table employee_tb1 drop column id;
Query OK, 6 rows affected (0.08 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from employee_tb1;
+------+---------------------+--------+
| name | data | singin |
+------+---------------------+--------+
| 小明 | 2016-04-22 15:25:33 | 1 |
| 小王 | 2016-04-20 15:25:47 | 3 |
| 小丽 | 2016-04-19 15:26:02 | 2 |
| 小王 | 2016-04-07 15:26:14 | 4 |
| 小明 | 2016-04-11 15:26:40 | 4 |
| 小明 | 2016-04-04 15:26:54 | 2 |
+------+---------------------+--------+
6 rows in set (0.00 sec)
(2)、添加字段
ALTER TABLE table
ADD [COLUMN] column_name_1 column_1_definition [FIRST|AFTER existing_column],
ADD [COLUMN] column_name_2 column_2_definition [FIRST|AFTER existing_column],
...;
注意:
FIRST
关键字将新列添加到表的第一列。 它还允许您使用AFTER existing_column
子句在现有列之后添加新列。如果没有明确指定新列的位置,MySQL会将其添加为最后一列。例子
mysql> alter table employee_tb1 add column id int(10) not null primary key auto_increment first;
Query OK, 0 rows affected, 1 warning (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> select * from employee_tb1;
+----+------+---------------------+--------+
| id | name | data | singin |
+----+------+---------------------+--------+
| 1 | 小明 | 2016-04-22 15:25:33 | 1 |
| 2 | 小王 | 2016-04-20 15:25:47 | 3 |
| 3 | 小丽 | 2016-04-19 15:26:02 | 2 |
| 4 | 小王 | 2016-04-07 15:26:14 | 4 |
| 5 | 小明 | 2016-04-11 15:26:40 | 4 |
| 6 | 小明 | 2016-04-04 15:26:54 | 2 |
+----+------+---------------------+--------+
6 rows in set (0.00 sec)
mysql> ALTER TABLE 表名 primary key(字段名);
注意:这个字段名已经存在了;否则可以使用如下方式:
mysql> ALTER TABLE 表名 ADD int(10) primary key;
mysql> ALTER TABLE 表名 MODIFY 字段名 定义;
例如:修改字段name为char(20);
mysql> alter table employee_tb1 modify name char(20);
Query OK, 6 rows affected (0.10 sec)
Records: 6 Duplicates: 0 Warnings: 0
当你修改字段时,你可以指定是否包含值或者是否设置默认值。
mysql> ALTER TABLE 表名 MODIFY 列名 INT NOT NULL DEFAULT 100;
如果你不设置默认值,MySQL会自动设置该字段默认为 NULL。
ALTER TABLE 表名 ALTER 字段名 SET DEFAULT 值;
注意:这里修改使用了关键字ALTER
和SET
.
mysql> SHOW TABLE STATUS LIKE 'testalter_tbl'\G;
mysql> ALTER TABLE 表名 RENAME TO 新表名;
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
索引分单列索引和组合索引。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
CREATE INDEX indexName ON mytable(username(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 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 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 ,用于全文索引。
删除:
ALTER TABLE testalter_tbl DROP INDEX index_name;
mysql> SHOW INDEX FROM table_name; \G
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。
创建语法
CREATE TEMPORARY TABLE 临时表名(column_name column_type);
删除语法
DROP TABLE 临时表名:
完全的复制MySQL的数据表,包括表的结构,索引,默认值等。
方法一:
步骤:
方法二:
CREATE TABLE 新表 select * from 旧表 where 1=2;
-- 或者
CREATE TABLE 新表 LIKE 旧表;
CREATE TABLE 新表 select * from 旧表;
MySQL 序列是一组整数:1, 2, 3, …,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现。
MySQL中最简单使用序列的方法就是使用MySQL AUTO_INCREMENT 来定义。
在定义表的时候定义:
mysql> CREATE TABLE insect
-> (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
-> name VARCHAR(30) NOT NULL, # type of insect
-> date DATE NOT NULL, # date collected
-> origin VARCHAR(30) NOT NULL # where collected
);
也可使用ALTER修改
mysql> ALTER TABLE 表名 MODIFY 列名 INT NOT NULL RPIMARY KEY AUTO_INCREMENT;
mysql> SELECT LAST_INSERT_ID();
mysql> CREATE TABLE insect
-> (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (id),
-> name VARCHAR(30) NOT NULL,
-> date DATE NOT NULL,
-> origin VARCHAR(30) NOT NULL
)engine=innodb auto_increment=100 charset=utf8;
或者
mysql> ALTER TABLE t AUTO_INCREMENT = 100;
你可以在 MySQL 数据表中设置指定的字段为 PRIMARY KEY(主键) 或者 UNIQUE(唯一) 索引来保证数据的唯一性。
设置表中字段 first_name,last_name 数据不能重复,你可以设置双主键模式来设置数据的唯一性.
CREATE TABLE person_tbl
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
PRIMARY KEY (last_name, first_name)
);
INSERT IGNORE INTO 与 INSERT INTO 的区别就是 INSERT IGNORE 会忽略数据库中已经存在的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据。这样就可以保留数据库中已经存在数据,达到在间隙中插入数据的目的。
CREATE TABLE person_tbl
(
first_name CHAR(20) NOT NULL,
last_name CHAR(20) NOT NULL,
sex CHAR(10),
UNIQUE (last_name, first_name)
);
mysql> SELECT COUNT(*) as repetitions, last_name, first_name
-> FROM person_tbl
-> GROUP BY last_name, first_name
-> HAVING repetitions > 1;
mysql> SELECT DISTINCT last_name, first_name
-> FROM person_tbl;
mysql> CREATE TABLE tmp SELECT last_name, first_name, sex FROM person_tbl GROUP BY (last_name, first_name, sex);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;
或者
mysql> ALTER IGNORE TABLE person_tbl
-> ADD PRIMARY KEY (last_name, first_name);
函数 | 描述 | 实例 |
---|---|---|
ASCII(s) | 返回字符串 s 的第一个字符的 ASCII 码。 | 返回 CustomerName 字段第一个字母的 ASCII 码:SELECT ASCII(CustomerName) AS NumCodeOfFirstChar FROM Customers; |
CHAR_LENGTH(s) | 返回字符串 s 的字符数 | 返回字符串 RUNOOB 的字符数SELECT CHAR_LENGTH("RUNOOB") AS LengthOfString; |
CHARACTER_LENGTH(s) | 返回字符串 s 的字符数 | 返回字符串 RUNOOB 的字符数SELECT CHARACTER_LENGTH("RUNOOB") AS LengthOfString; |
CONCAT(s1,s2…sn) | 字符串 s1,s2 等多个字符串合并为一个字符串 | 合并多个字符串SELECT CONCAT("SQL ", "Runoob ", "Gooogle ", "Facebook") AS ConcatenatedString; |
CONCAT_WS(x, s1,s2…sn) | 同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 | 合并多个字符串,并添加分隔符:SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString; |
FIELD(s,s1,s2…) | 返回第一个字符串 s 在字符串列表(s1,s2…)中的位置 | 返回字符串 c 在列表值中的位置:SELECT FIELD("c", "a", "b", "c", "d", "e"); |
FIND_IN_SET(s1,s2) | 返回在字符串s2中与s1匹配的字符串的位置 | 返回字符串 c 在指定字符串中的位置:SELECT FIND_IN_SET("c", "a,b,c,d,e"); |
FORMAT(x,n) | 函数可以将数字 x 进行格式化 “#,###.##”, 将 x 保留到小数点后 n 位,最后一位四舍五入。 | 格式化数字 “#,###.##” 形式:SELECT FORMAT(250500.5634, 2); -- 输出 250,500.56 |
INSERT(s1,x,len,s2) | 字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 | 从字符串第一个位置开始的 6 个字符替换为 runoob:SELECT INSERT("google.com", 1, 6, "runnob"); -- 输出:runoob.com |
LOCATE(s1,s) | 从字符串 s 中获取 s1 的开始位置 | 获取 b 在字符串 abc 中的位置:SELECT LOCATE('st','myteststring'); -- 5 返回字符串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2 |
LCASE(s) | 将字符串 s 的所有字母变成小写字母 | 字符串 RUNOOB 转换为小写:SELECT LCASE('RUNOOB') -- runoob |
LEFT(s,n) | 返回字符串 s 的前 n 个字符 | 返回字符串 runoob 中的前两个字符:SELECT LEFT('runoob',2) -- ru |
LOWER(s) | 将字符串 s 的所有字母变成小写字母 | 字符串 RUNOOB 转换为小写:SELECT LOWER('RUNOOB') -- runoob |
LPAD(s1,len,s2) | 在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len | 将字符串 xx 填充到 abc 字符串的开始处:SELECT LPAD('abc',5,'xx') -- xxabc |
LTRIM(s) | 去掉字符串 s 开始处的空格 | 去掉字符串 RUNOOB开始处的空格:SELECT LTRIM(" RUNOOB") AS LeftTrimmedString;-- RUNOOB |
MID(s,n,len) | 从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len) | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT MID("RUNOOB", 2, 3) AS ExtractString; -- UNO |
POSITION(s1 IN s) | 从字符串 s 中获取 s1 的开始位置 | 返回字符串 abc 中 b 的位置:SELECT POSITION('b' in 'abc') -- 2 |
REPEAT(s,n) | 将字符串 s 重复 n 次 | 将字符串 runoob 重复三次:SELECT REPEAT('runoob',3) -- runoobrunoobrunoob |
REPLACE(s,s1,s2) | 将字符串 s2 替代字符串 s 中的字符串 s1 | 将字符串 abc 中的字符 a 替换为字符 x:SELECT REPLACE('abc','a','x') --xbc |
REVERSE(s) | 将字符串s的顺序反过来 | 将字符串 abc 的顺序反过来:SELECT REVERSE('abc') -- cba |
RIGHT(s,n) | 返回字符串 s 的后 n 个字符 | 返回字符串 runoob 的后两个字符:SELECT RIGHT('runoob',2) -- ob |
RPAD(s1,len,s2) | 在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len | 将字符串 xx 填充到 abc 字符串的结尾处:SELECT RPAD('abc',5,'xx') -- abcxx |
RTRIM(s) | 去掉字符串 s 结尾处的空格 | 去掉字符串 RUNOOB 的末尾空格:SELECT RTRIM("RUNOOB ") AS RightTrimmedString; -- RUNOOB |
SPACE(n) | 返回 n 个空格 | 返回 10 个空格:SELECT SPACE(10); |
STRCMP(s1,s2) | 比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1比较字符串: |
SELECT STRCMP("runoob", "runoob"); -- 0 |
SUBSTR(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTR("RUNOOB", 2, 3) AS ExtractString; -- UNO |
SUBSTRING(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 | 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString; -- UNO |
SUBSTRING_INDEX(s, delimiter, number) | 返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。 如果 number 是正数,返回第 number 个字符左边的字符串。 如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。 | SELECT SUBSTRING_INDEX('a*b','*',1) -- a SELECT SUBSTRING_INDEX('a*b','*',-1) -- b SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a*b*c*d*e','*',3),'*',-1) -- c |
TRIM(s) | 去掉字符串 s 开始和结尾处的空格 | 去掉字符串 RUNOOB 的首尾空格:SELECT TRIM(' RUNOOB ') AS TrimmedString; |
UCASE(s) | 将字符串转换为大写 | 将字符串 runoob 转换为大写:SELECT UCASE("runoob"); -- RUNOOB |
UPPER(s) | 将字符串转换为大写 | 将字符串 runoob 转换为大写:SELECT UPPER("runoob"); -- RUNOOB |
函数名 | 描述 | 实例 |
---|---|---|
ABS(x) | 返回 x 的绝对值 | 返回 -1 的绝对值:SELECT ABS(-1) -- 返回1 |
ACOS(x) | 求 x 的反余弦值(参数是弧度) | SELECT ACOS(0.25); |
ASIN(x) | 求反正弦值(参数是弧度) | SELECT ASIN(0.25); |
ATAN(x) | 求反正切值(参数是弧度) | SELECT ATAN(2.5); |
ATAN2(n, m) | 求反正切值(参数是弧度) | SELECT ATAN2(-0.8, 2); |
AVG(expression) | 返回一个表达式的平均值,expression 是一个字段 | 返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products; |
CEIL(x) | 返回大于或等于 x 的最小整数 | SELECT CEIL(1.5) -- 返回2 |
CEILING(x) | 返回大于或等于 x 的最小整数 | SELECT CEILING(1.5); -- 返回2 |
COS(x) | 求余弦值(参数是弧度) | SELECT COS(2); |
COT(x) | 求余切值(参数是弧度) | SELECT COT(6); |
COUNT(expression) | 返回查询的记录总数,expression 参数是一个字段或者 * 号 | 返回 Products 表中 products 字段总共有多少条记录:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products; |
DEGREES(x) | 将弧度转换为角度 | SELECT DEGREES(3.1415926535898) -- 180 |
n DIV m | 整除,n 为被除数,m 为除数 | 计算 10 除于 5:SELECT 10 DIV 5; -- 2 |
EXP(x) | 返回 e 的 x 次方 | 计算 e 的三次方:SELECT EXP(3) -- 20.085536923188 |
FLOOR(x) | 返回小于或等于 x 的最大整数 | 小于或等于 1.5 的整数:SELECT FLOOR(1.5) -- 返回1 |
GREATEST(expr1, expr2, expr3, …) | 返回列表中的最大值 | 返回以下数字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34 返回以下字符串列表中的最大值:SELECT GREATEST("Google", "Runoob", "Apple"); -- Runoob |
LEAST(expr1, expr2, expr3, …) | 返回列表中的最小值 | 返回以下数字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3 返回以下字符串列表中的最小值:SELECT LEAST("Google", "Runoob", "Apple"); -- Apple |
LN | 返回数字的自然对数,以 e 为底。 | 返回 2 的自然对数:SELECT LN(2); -- 0.6931471805599453 |
LOG(x) 或 LOG(base, x) | 返回自然对数(以 e 为底的对数),如果带有 base 参数,则 base 为指定带底数。 | SELECT LOG(20.085536923188) -- 3 SELECT LOG(2, 4); -- 2 |
LOG10(x) | 返回以 10 为底的对数 | SELECT LOG10(100) -- 2 |
LOG2(x) | 返回以 2 为底的对数 | 返回以 2 为底 6 的对数:SELECT LOG2(6); -- 2.584962500721156 |
MAX(expression) | 返回字段 expression 中的最大值 | 返回数据表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products; |
MIN(expression) | 返回字段 expression 中的最小值 | 返回数据表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS LargestPrice FROM Products; |
MOD(x,y) | 返回 x 除以 y 以后的余数 | 5 除于 2 的余数:SELECT MOD(5,2) -- 1 |
PI() | 返回圆周率(3.141593) | SELECT PI() --3.141593 |
POW(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POW(2,3) -- 8 |
POWER(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POWER(2,3) -- 8 |
RADIANS(x) | 将角度转换为弧度 | 180 度转换为弧度:SELECT RADIANS(180) -- 3.1415926535898 |
RAND() | 返回 0 到 1 的随机数 | SELECT RAND() --0.93099315644334 |
ROUND(x) | 返回离 x 最近的整数 | SELECT ROUND(1.23456) --1 |
SIGN(x) | 返回 x 的符号,x 是负数、0、正数分别返回 -1、0 和 1 | SELECT SIGN(-10) -- (-1) |
SIN(x) | 求正弦值(参数是弧度) | SELECT SIN(RADIANS(30)) -- 0.5 |
SQRT(x) | 返回x的平方根 | 25 的平方根:SELECT SQRT(25) -- 5 |
SUM(expression) | 返回指定字段的总和 | 计算 OrderDetails 表中字段 Quantity 的总和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails; |
TAN(x) | 求正切值(参数是弧度) | SELECT TAN(1.75); -- -5.52037992250933 |
TRUNCATE(x,y) | 返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入) | SELECT TRUNCATE(1.23456,3) -- 1.234 |
函数名 | 描述 | 实例 |
---|---|---|
ADDDATE(d,n) | 计算起始日期 d 加上 n 天的日期 | SELECT ADDDATE("2017-06-15", INTERVAL 10 DAY); ->2017-06-25 |
ADDTIME(t,n) | 时间 t 加上 n 秒的时间 | SELECT ADDTIME('2011-11-11 11:11:11', 5) ->2011-11-11 11:11:16 (秒) |
CURDATE() | 返回当前日期 | SELECT CURDATE(); -> 2018-09-19 |
CURRENT_DATE() | 返回当前日期 | SELECT CURRENT_DATE(); -> 2018-09-19 |
CURRENT_TIME | 返回当前时间 | SELECT CURRENT_TIME(); -> 19:59:02 |
CURRENT_TIMESTAMP() | 返回当前日期和时间 | SELECT CURRENT_TIMESTAMP() -> 2018-09-19 20:57:43 |
CURTIME() | 返回当前时间 | SELECT CURTIME(); -> 19:59:02 |
DATE() | 从日期或日期时间表达式中提取日期值 | SELECT DATE("2017-06-15"); -> 2017-06-15 |
DATEDIFF(d1,d2) | 计算日期 d1->d2 之间相隔的天数 | SELECT DATEDIFF('2001-01-01','2001-02-02') -> -32 |
DATE_ADD(d,INTERVAL expr type) | 计算起始日期 d 加上一个时间段后的日期 | SELECT ADDDATE('2011-11-11 11:11:11',1) -> 2011-11-12 11:11:11 (默认是天) SELECT ADDDATE('2011-11-11 11:11:11', INTERVAL 5 MINUTE) -> 2011-11-11 11:16:11 (TYPE的取值与上面那个列出来的函数类似) |
DATE_FORMAT(d,f) | 按表达式 f的要求显示日期 d | SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r') -> 2011-11-11 11:11:11 AM |
DATE_SUB(date,INTERVAL expr type) | 函数从日期减去指定的时间间隔。 | Orders 表中 OrderDate 字段减去 2 天:SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY) AS OrderPayDate FROM Orders |
DAY(d) | 返回日期值 d 的日期部分 | SELECT DAY("2017-06-15"); -> 15 |
DAYNAME(d) | 返回日期 d 是星期几,如 Monday,Tuesday | SELECT DAYNAME('2011-11-11 11:11:11') ->Friday |
DAYOFMONTH(d) | 计算日期 d 是本月的第几天 | SELECT DAYOFMONTH('2011-11-11 11:11:11') ->11 |
DAYOFWEEK(d) | 日期 d 今天是星期几,1 星期日,2 星期一,以此类推 | SELECT DAYOFWEEK('2011-11-11 11:11:11') ->6 |
DAYOFYEAR(d) | 计算日期 d 是本年的第几天 | SELECT DAYOFYEAR('2011-11-11 11:11:11') ->315 |
EXTRACT(type FROM d) | 从日期 d 中获取指定的值,type 指定返回的值。 type可取值为: MICROSECONDSECONDMINUTEHOURDAYWEEKMONTHQUARTERYEARSECOND_MICROSECONDMINUTE_MICROSECONDMINUTE_SECONDHOUR_MICROSECONDHOUR_SECONDHOUR_MINUTEDAY_MICROSECONDDAY_SECONDDAY_MINUTEDAY_HOURYEAR_MONTH | SELECT EXTRACT(MINUTE FROM '2011-11-11 11:11:11') -> 11 |
FROM_DAYS(n) | 计算从 0000 年 1 月 1 日开始 n 天后的日期 | SELECT FROM_DAYS(1111) -> 0003-01-16 |
HOUR(t) | 返回 t 中的小时值 | SELECT HOUR('1:2:3') -> 1 |
LAST_DAY(d) | 返回给给定日期的那一月份的最后一天 | SELECT LAST_DAY("2017-06-20"); -> 2017-06-30 |
LOCALTIME() | 返回当前日期和时间 | SELECT LOCALTIME() -> 2018-09-19 20:57:43 |
LOCALTIMESTAMP() | 返回当前日期和时间 | SELECT LOCALTIMESTAMP() -> 2018-09-19 20:57:43 |
MAKEDATE(year, day-of-year) | 基于给定参数年份 year 和所在年中的天数序号 day-of-year 返回一个日期 | SELECT MAKEDATE(2017, 3); -> 2017-01-03 |
MAKETIME(hour, minute, second) | 组合时间,参数分别为小时、分钟、秒 | SELECT MAKETIME(11, 35, 4); -> 11:35:04 |
MICROSECOND(date) | 返回日期参数所对应的微秒数 | SELECT MICROSECOND("2017-06-20 09:34:00.000023"); -> 23 |
MINUTE(t) | 返回 t 中的分钟值 | SELECT MINUTE('1:2:3') -> 2 |
MONTHNAME(d) | 返回日期当中的月份名称,如 November | SELECT MONTHNAME('2011-11-11 11:11:11') -> November |
MONTH(d) | 返回日期d中的月份值,1 到 12 | SELECT MONTH('2011-11-11 11:11:11') ->11 |
NOW() | 返回当前日期和时间 | SELECT NOW() -> 2018-09-19 20:57:43 |
PERIOD_ADD(period, number) | 为 年-月 组合日期添加一个时段 | SELECT PERIOD_ADD(201703, 5); -> 201708 |
PERIOD_DIFF(period1, period2) | 返回两个时段之间的月份差值 | SELECT PERIOD_DIFF(201710, 201703); -> 7 |
QUARTER(d) | 返回日期d是第几季节,返回 1 到 4 | SELECT QUARTER('2011-11-11 11:11:11') -> 4 |
SECOND(t) | 返回 t 中的秒钟值 | SELECT SECOND('1:2:3') -> 3 |
SEC_TO_TIME(s) | 将以秒为单位的时间 s 转换为时分秒的格式 | SELECT SEC_TO_TIME(4320) -> 01:12:00 |
STR_TO_DATE(string, format_mask) | 将字符串转变为日期 | SELECT STR_TO_DATE("August 10 2017", "%M %d %Y"); -> 2017-08-10 |
SUBDATE(d,n) | 日期 d 减去 n 天后的日期 | SELECT SUBDATE('2011-11-11 11:11:11', 1) ->2011-11-10 11:11:11 (默认是天) |
SUBTIME(t,n) | 时间 t 减去 n 秒的时间 | SELECT SUBTIME('2011-11-11 11:11:11', 5) ->2011-11-11 11:11:06 (秒) |
SYSDATE() | 返回当前日期和时间 | SELECT SYSDATE() -> 2018-09-19 20:57:43 |
TIME(expression) | 提取传入表达式的时间部分 | SELECT TIME("19:30:10"); -> 19:30:10 |
TIME_FORMAT(t,f) | 按表达式 f 的要求显示时间 t | SELECT TIME_FORMAT('11:11:11','%r') 11:11:11 AM |
TIME_TO_SEC(t) | 将时间 t 转换为秒 | SELECT TIME_TO_SEC('1:12:00') -> 4320 |
TIMEDIFF(time1, time2) | 计算时间差值 | SELECT TIMEDIFF("13:10:11", "13:10:10"); -> 00:00:01 |
TIMESTAMP(expression, interval) | 单个参数时,函数返回日期或日期时间表达式;有2个参数时,将参数加和 | SELECT TIMESTAMP("2017-07-23", "13:10:11"); -> 2017-07-23 13:10:11 |
TO_DAYS(d) | 计算日期 d 距离 0000 年 1 月 1 日的天数 | SELECT TO_DAYS('0001-01-01 01:01:01') -> 366 |
WEEK(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 | SELECT WEEK('2011-11-11 11:11:11') -> 45 |
WEEKDAY(d) | 日期 d 是星期几,0 表示星期一,1 表示星期二 | SELECT WEEKDAY("2017-06-15"); -> 3 |
WEEKOFYEAR(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 | SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45 |
YEAR(d) | 返回年份 | SELECT YEAR("2017-06-15"); -> 2017 |
YEARWEEK(date, mode) | 返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 | SELECT YEARWEEK("2017-06-15"); -> 201724 |
函数名 | 描述 | 实例 |
---|---|---|
BIN(x) | 返回 x 的二进制编码 | 15 的 2 进制编码:SELECT BIN(15); -- 1111 |
BINARY(s) | 将字符串 s 转换为二进制字符串 | SELECT BINARY "RUNOOB"; -> RUNOOB |
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE result END |
CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。 | SELECT CASE WHEN 1 > 0 THEN '1 > 0' WHEN 2 > 0 THEN '2 > 0' ELSE '3 > 0' END ->1 > 0 |
CAST(x AS type) | 转换数据类型 | 字符串日期转换为日期:SELECT CAST("2017-08-29" AS DATE); -> 2017-08-29 |
COALESCE(expr1, expr2, …, expr_n) | 返回参数中的第一个非空表达式(从左向右) | SELECT COALESCE(NULL, NULL, NULL, 'runoob.com', NULL, 'google.com'); -> runoob.com |
CONNECTION_ID() | 返回服务器的连接数 | SELECT CONNECTION_ID(); -> 4292835 |
CONV(x,f1,f2) | 返回 f1 进制数变成 f2 进制数 | SELECT CONV(15, 10, 2); -> 1111 |
CONVERT(s USING cs) | 函数将字符串 s 的字符集变成 cs | SELECT CHARSET('ABC') ->utf-8 SELECT CHARSET(CONVERT('ABC' USING gbk)) ->gbk |
CURRENT_USER() | 返回当前用户 | SELECT CURRENT_USER(); -> guest@% |
DATABASE() | 返回当前数据库名 | SELECT DATABASE(); -> runoob |
IF(expr,v1,v2) | 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。 | SELECT IF(1 > 0,'正确','错误') ->正确 |
IFNULL(v1,v2) | 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。 | SELECT IFNULL(null,'Hello Word') ->Hello Word |
ISNULL(expression) | 判断表达式是否为 NULL | SELECT ISNULL(NULL); ->1 |
LAST_INSERT_ID() | 返回最近生成的 AUTO_INCREMENT 值 | SELECT LAST_INSERT_ID(); ->6 |
NULLIF(expr1, expr2) | 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1 | SELECT NULLIF(25, 25); -> |
SESSION_USER() | 返回当前用户 | SELECT SESSION_USER(); -> guest@% |
SYSTEM_USER() | 返回当前用户 | SELECT SYSTEM_USER(); -> guest@% |
USER() | 返回当前用户 | SELECT USER(); -> guest@% |
VERSION() | 返回数据库的版本号 | SELECT VERSION() -> 5.6.34 |
MySQL 支持的算术运算符包括:
运算符 | 作用 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ 或 DIV | 除法 |
% 或 MOD | 取余 |
符号 | 描述 | 备注 |
---|---|---|
= | 等于 | |
<>, != | 不等于 | |
> | 大于 | |
< | 小于 | |
<= | 小于等于 | |
>= | 大于等于 | |
BETWEEN | 在两值之间 | >=min&&<=max |
NOT BETWEEN | 不在两值之间 | |
IN | 在集合中 | |
NOT IN | 不在集合中 | |
<=> | 严格比较两个NULL值是否相等 | 两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 |
LIKE | 模糊匹配 | |
REGEXP 或 RLIKE | 正则式匹配 | |
IS NULL | 为空 | |
IS NOT NULL | 不为空 |
运算符号 | 作用 |
---|---|
NOT 或 ! | 逻辑非 |
AND | 逻辑与 |
OR | 逻辑或 |
XOR | 逻辑异或 |
运算符号 | 作用 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
! | 取反 |
<< | 左移 |
>> | 右移 |
MySQL 视图(View)是一种虚拟存在的表,同真实表一样,视图也由列和行构成,但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表,并且还是在使用视图时动态生成的。
数据库中只存放了视图的定义,并没有存放视图中的数据,这些数据都存放在定义视图查询所引用的真实表中。使用视图查询数据时,数据库会从真实表中取出对应的数据。因此,视图中的数据是依赖于真实表中的数据的。一旦真实表中的数据发生改变,显示在视图中的数据也会发生改变。
语法
CREATE VIEW <视图名> AS
查询视图:可以用SELECT语句
DESCRIBE/DESC 视图名;
-- 查看视图的详细信息
SHOW CREATE VIEW 视图名;
修改视图
ALTER VIEW <视图名> AS
删除视图
DROP VIEW <视图名1> [ , <视图名2> …]
存储过程是一组为了完成特定功能的 SQL 语句集合。使用存储过程的目的是将常用或复杂的工作预先用 SQL 语句写好并用一个指定名称存储起来,这个过程经编译和优化后存储在数据库服务器中,因此称为存储过程。当以后需要数据库提供与已定义好的存储过程的功能相同的服务时,只需调用“CALL存储过程名字”即可自动完成。
语法
CREATE PROCEDURE <过程名> ( [过程参数[,…] ] ) <过程体>
[过程参数[,…] ] 格式
[ IN | OUT | INOUT ] <参数名> <类型>
参数说明:
存储过程的名称,默认在当前数据库中创建。若需要在特定数据库中创建存储过程,则要在名称前面加上数据库的名称,即 db_name.sp_name。
需要注意的是,名称应当尽量避免选取与 MySQL 内置函数相同的名称,否则会发生错误。
存储过程的参数列表。其中,<参数名>
为参数名,<类型>
为参数的类型(可以是任何有效的 MySQL 数据类型)。当有多个参数时,参数列表中彼此间用逗号分隔。存储过程可以没有参数(此时存储过程的名称后仍需加上一对括号),也可以有 1 个或多个参数。
MySQL 存储过程支持三种类型的参数,即输入参数、输出参数和输入/输出参数,分别用 IN、OUT 和 INOUT 三个关键字标识。其中,输入参数可以传递给一个存储过程,输出参数用于存储过程需要返回一个操作结果的情形,而输入/输出参数既可以充当输入参数也可以充当输出参数。
需要注意的是,参数的取名不要与数据表的列名相同,否则尽管不会返回出错信息,但是存储过程的 SQL 语句会将参数名看作列名,从而引发不可预知的结果。
存储过程的主体部分,也称为存储过程体,包含在过程调用的时候必须执行的 SQL 语句。这个部分以关键字 BEGIN 开始,以关键字 END 结束。若存储过程体中只有一条 SQL 语句,则可以省略 BEGIN-END 标志。
在存储过程的创建中,经常会用到一个十分重要的 MySQL 命令,即 DELIMITER 命令,特别是对于通过命令行的方式来操作 MySQL 数据库的使用者,更是要学会使用该命令。
在 MySQL 中,服务器处理 SQL 语句默认是以分号作为语句结束标志的。然而,在创建存储过程时,存储过程体可能包含有多条 SQL 语句,这些 SQL 语句如果仍以分号作为语句结束符,那么 MySQL 服务器在处理时会以遇到的第一条 SQL 语句结尾处的分号作为整个程序的结束符,而不再去处理存储过程体中后面的 SQL 语句,这样显然不行。
查看存储过程状态:
SHOW PROCEDURE STATUS LIKE 存储过程名;
删除存储过程:
DROP PROCEDURE [ IF EXISTS ] <过程名>
MySQL 的触发器和存储过程一样,都是嵌入到 MySQL 中的一段程序,是 MySQL 中管理数据的有力工具。不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,而是通过对数据表的相关操作来触发、激活从而实现执行。比如当对 student 表进行操作(INSERT,DELETE 或 UPDATE)时就会激活它执行。
创建语法
CREATE <触发器名> < BEFORE | AFTER >
ON <表名> FOR EACH Row<触发器主体>
触发器的名称,触发器在当前数据库中必须具有唯一的名称。如果要在某个特定数据库中创建,名称前面应该加上数据库的名称。
触发事件,用于指定激活触发器的语句的种类。
注意:三种触发器的执行时间如下。
BEFORE 和 AFTER,触发器被触发的时刻,表示触发器是在激活它的语句之前或之后触发。若希望验证新数据是否满足条件,则使用 BEFORE 选项;若希望在激活触发器的语句执行之后完成几个或更多的改变,则通常使用 AFTER 选项。
与触发器相关联的表名,此表必须是永久性表,不能将触发器与临时表或视图关联起来。在该表上触发事件发生时才会激活触发器。同一个表不能拥有两个具有相同触发时刻和事件的触发器。例如,对于一张数据表,不能同时有两个 BEFORE UPDATE 触发器,但可以有一个 BEFORE UPDATE 触发器和一个 BEFORE INSERT 触发器,或一个 BEFORE UPDATE 触发器和一个 AFTER UPDATE 触发器。
触发器动作主体,包含触发器激活时将要执行的 MySQL 语句。如果要执行多个语句,可使用 BEGIN…END 复合语句结构。
一般是指行级触发,对于受触发事件影响的每一行都要激活触发器的动作。例如,使用 INSERT 语句向某个表中插入多行数据时,触发器会对每一行数据的插入都执行相应的触发器动作。