MYSQL
说明:mysql是数据库的一种,sql是专门用来与数据库通信的语言。 SQLyog是MySQL图形化管理工具的一种 启动:net start mysql80 关闭:net stop mysql80
在功能上主要分为如下3大类: DDL(Data Definition Languages、数据定义语言) DML(Data Manipulation Language、数据操作语言) DCL(Data Control Language、数据控制语言)
SQL语言
- SQL语言的规则和规范
- 伪表DUAL
- SELECT ... FROM ...
- 列的别名
- 去除重复行DISTINCT
- 空值参与运算
- 着重号
- 查询常数
- 显示表结构DESCRIBE或DESC
- 过滤数据WHERE
- 算术运算符+,-,*,/,%
- 比较运算符=,<=>,<>,!=,<,<=,>,>=;
-
- 非符号类型的运算符
-
- IN运算符和NOT IN运算符
-
- 逻辑运算符(&& ,II, !, XOR)
- 位运算符
- 多表查询
- 聚合函数
- 子查询
- 创建和管理表
- 数据处理之增删改
- 排序与分页
- MySQL数据类型
- 视图
- 存储过程与存储函数
- 变量、流程控制与游标
- 触发器
导入数据:
source 数据目录
SQL语言的规则和规范
SQL 可以写在一行或者多行。为了提高可读性,各子句分行写,必要时使用缩进
每条命令以 ; 或 \g 或 \G 结束
关键字不能被缩写也不能分行
关于标点符号 必须保证所有的()、单引号、双引号是成对结束的 必须使用英文状态下的半角输入方式
字符串型和日期时间类型的数据可以使用单引号(’ ')表示 列的别名,尽量使用双引号(" "),而且不建议省略as
SQL大小写规范 (建议遵守)
MySQL 在 Windows 环境下是大小写不敏感的,MySQL 在 Linux 环境下是大小写敏感的
数据库名、表名、表的别名、变量名是严格区分大小写的 关键字、函数名、列名(或字段名)、列的别名(字段的别名) 是忽略大小写的。 推荐采用统一的书写规范: 数据库名、表名、表别名、字段名、字段别名等都小写 SQL 关键字、函数名、绑定在·变量等都大写 注 释 可以使用如下格式的注释结构 单行注释:#注释文字(MySQL特有的方式) 单行注释:-- 注释文字(–后面必须包含一个空格。) 多行注释:/* 注释文字 */
这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。
SELECT *
FROM information_schema.table_constraints
WHERE TABLE_NAME = 'employees';
CREATE TABLE emp(
id INT(10) NOT NULL,
NAME VARCHAR(20) NOT NULL,
sex CHAR NULL
);
DESC emp;
ALTER TABLE students
MODIFY sname VARCHAR(20) NOT NULL;
ALTER TABLE emp
MODIFY id INT(10) NULL;
CREATE TABLE test2(
id INT UNIQUE,
last_name VARCHAR(15),
email VARCHAR(25),
salary DECIMAL(10,2),
CONSTRAINT te2 UNIQUE(email)
);
DESC test2;
SELECT *
FROM information_schema.table_constraints
WHERE TABLE_NAME = 'test2';
ALTER TABLE test2
ADD CONSTRAINT sal UNIQUE(salary);
ALTER TABLE test2
MODIFY last_name VARCHAR(15) UNIQUE;
CREATE TABLE test3(
id INT NOT NULL,
NAME VARCHAR(25),
PASSWORD VARCHAR(16),
CONSTRAINT uk_name_pwd UNIQUE(NAME,PASSWORD)
);
INSERT INTO test3
VALUES(1,'张三','137');
INSERT INTO test3
VALUES(1,'李四','137');
SELECT *
FROM information_schema.table_constraints
WHERE TABLE_NAME = 'test2';
ALTER TABLE test2
DROP INDEX last_name;
CREATE TABLE test4(
id INT PRIMARY KEY,
last_name VARCHAR(15),
email VARCHAR(25),
salary DECIMAL(10,2)
);
CREATE TABLE test5(
id INT ,
last_name VARCHAR(15),
email VARCHAR(25),
salary DECIMAL(10,2),
PRIMARY KEY(id)
);
SELECT *
FROM information_schema.table_constraints
WHERE TABLE_NAME = 'test6';
CREATE TABLE test6(
id INT ,
last_name VARCHAR(15),
email VARCHAR(25),
salary DECIMAL(10,2)
);
ALTER TABLE test6
ADD PRIMARY KEY(id);
ALTER TABLE test6
DROP PRIMARY KEY;
CREATE TABLE test7(
id INT PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(15)
);
SELECT *
FROM test7;
INSERT INTO test7(last_name)
VALUES('tom');
INSERT INTO test7(last_name)
VALUES('tom');
INSERT INTO test7
VALUES(NULL,'tom');
SELECT *
FROM test7;
CREATE TABLE test8(
id INT PRIMARY KEY,
last_name VARCHAR(15)
);
ALTER TABLE test8
MODIFY id INT AUTO_INCREMENT;
CREATE TABLE dept1(
id INT PRIMARY KEY,
dept_name VARCHAR(15)
);
CREATE TABLE emp6(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(15),
department_id INT,
CONSTRAINT fedi FOREIGN KEY (department_id) REFERENCES dept1(id)
);
CREATE TABLE emp3(
id INT,
salary INT CHECK(salary>2000),
last_name VARCHAR(15)
);
INSERT INTO emp3(salary)
VALUES (2500);
INSERT INTO emp3(salary)
VALUES (2000);
CREATE TABLE emp4(
id INT,
salary INT DEFAULT 2000
);
INSERT INTO emp4
VALUE(1,6000);
INSERT INTO emp4(id)
VALUE(1);
SELECT *
FROM emp4;
ALTER TABLE emp4
MODIFY salary INT;
DESC emp4;
用于添加、删除、更新和查询数据库记 录,并检查数据完整性。SELECT是SQL语言的基础,最为重要。
伪表DUAL
SELECT 1+1
FROM DUAL;
SELECT … FROM …
语法:
SELECT 标识选择那些列
FROM 标识从哪个表中选择;
选择全部列
SELECT *
FROM 表名;
选择特定的列
SELECT 列名, 列名,......
FROM 表名;
列的别名
重命名一个列
便于计算
紧跟列名,也可以在列名和别名之间加入关键字AS,别名使用双引号,以便在别名中包含空格或特 殊的字符并区分大小写。
AS 可以省略
建议别名简短,见名知意
SELECT last_name AS ln
FROM 表名
去除重复行DISTINCT
SELECT DISTINCT 列名
空值参与运算
所有运算符或列值遇到null值,运算的结果都为null
着重号
列名或表名等与关键字或保留字重名,加上着重号以表示此名称不代表关键字或保留字。
SELECT `ORDER`
FROM 表名
查询常数
SELECT 查询还可以对常数进行查询。对的,就是在 SELECT 查询结果中增加一列固定的常数列。这列的取值是我们指定的,而不是从数据表中动态取出的。
为什么我们还要对常数进行查询呢?
SQL 中的 SELECT 语法的确提供了这个功能,一般来说我们只从一个表中查询数据,通常不需要增加一个 固定的常数列,但如果我们想整合不同的数据源,用常数列作为这个表的标记,就需要查询常数。 比如:
SELECT '呱呱' AS '哈哈'
FROM 表名;
显示表结构DESCRIBE或DESC
DESCRIBE 列名;
DESC 列名;
各个字段的含义分别解释如下:
Field:表示字段名称。
Type:表示字段类型,这里 barcode、goodsname 是文本型的,price 是整数类型的。
Null:表示该列是否可以存储NULL值。
Key:表示该列是否已编制索引。PRI表示该列是表主键的一部分;UNI表示该列是UNIQUE索引的一部分;MUL表示在列中某个给定值允许出现多次。
Default:表示该列是否有默认值,如果有,那么值是多少。
Extra:表示可以获取的与给定列有关的附加信息,例如AUTO_INCREMENT等。
过滤数据WHERE
过滤条件声明在FROM结构后面 列如:
SELECT *
FRMO 表名
WHERE 判断条件
算术运算符+,-,*,/,%
一个整数类型的值对整数进行加法和减法操作,结果还是一个整数; 一个整数类型的值对浮点数进行加法和减法操作,结果是一个浮点数; 加法和减法的优先级相同,进行先加后减操作与进行先减后加操作的结果是一样的;
在Java中,+的左右两边如果有字符串,那么表示字符串的拼接。但是在MySQL中+只表示数值相加。如果遇到非数值类型,先尝试转成数值,如果转失败,就按0计算。(补充:MySQL中字符串拼接要使用字符串函数CONCAT()实现)
一个数乘以整数1和除以整数1后仍得原数;
一个数乘以浮点数1和除以浮点数1后变成浮点数,数值与原数相等;
一个数除以整数后,不管是否能除尽,结果都为一个浮点数;
一个数除以另一个数,除不尽时,结果为一个浮点数,并保留到小数点后4位;
乘法和除法的优先级相同,进行先乘后除操作与先除后乘操作,得出的结果相同。
在数学运算中,0不能用作除数,在MySQL中,一个数除以0为NULL。
如下:
SELECT 100+'1'
FROM DUAL;
SELECT 100+'a'
FROM DUAL;
SELECT 100+NULL
FROM DUAL;
# % 运算符的结果的正负号与被除数一致
比较运算符=,<=>,<>,!=,<,<=,>,>=;
比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL。
比较运算符经常被用来作为SELECT查询语句的条件来使用,返回符合条件的结果记录。
等号运算符 =
等号运算符(=)判断等号两边的值、字符串或表达式是否相等,如果相等则返回1,不相等则返回0。
在使用等号运算符时,遵循如下规则:
如果等号两边的值、字符串或表达式都为字符串,则MySQL会按照字符串进行比较,其比较的是每个字符串中字符的ANSI编码是否相等
如果等号两边的值都是整数,则MySQL会按照整数来比较两个值的大小。
如果等号两边的值一个是整数,另一个是字符串,则MySQL会将字符串转化为数字进行比较。
如果等号两边的值、字符串或表达式中有一个为NULL,则比较结果为NULL。
安全等与运算符 <=>
两边的操作数的值都为NULL时,返回的结果为1而不是NULL,其他 返回结果与等于运算符相同。
不等于运算符(<>和!=)
用于判断两边的数字、字符串或者表达式的值是否不相等
如果不相等则返回1,相等则返回0。不等于运算符不能判断NULL值。如果两边的值有任意一个为NULL,或两边都为NULL,则结果为NULL
非符号类型的运算符
空运算符(IS NULL或者ISNULL)和 非空运算符(IS NOT NULL)
空:判断一个值是否为NULL,如果为NULL则返回1,否则返回 0。
非空:判断一个值是否不为NULL,如果不为NULL则返回1,否则返 回0。
SELECT last_name ,commission_pct
FROM employees
WHERE commission_pct IS NULL;
SELECT commission_pct
FROM employees
WHERE NOT commission_pct <=>NULL;
最小值运算符LEAST和最大值运算符GREATEST
最小值运算符 语法格式为:LEAST(值1,值2,…,值n)。其中,“值n”表示参数列表中有n个值。在有两个或多个参数的情况下,返回最小值。当参数为字符串时,返回字母表中顺序最靠前的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。
最大值运算符 语法格式为:GREATEST(值1,值2,…,值n)。其中,n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值。当参数为字符串时,返回字母表中顺序最靠后的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。
SELECT LEAST(first_name,last_name),GREATEST(2,3)
FROM employees;
BETWEEN AND运算符
BETWEEN运算符使用的格式通常为SELECT D FROM TABLE WHERE C BETWEEN A AND B,此时,当C大于或等于A,并且C小于或等于B时,结果为1,否则结果为0。
SELECT first_name ,salary
FROM employees
WHERE salary NOT BETWEEN 4000 AND 8000
IN运算符和NOT IN运算符
IN运算符用于判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给定的值为NULL,或者IN列表中存在NULL,则结果为NULL。
NOT IN运算符用于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一个值,则返回1,否则返回0。
SELECT first_name ,department_id
FROM employees
**
WHERE department_id IN(10,20,30);
LIKE运算符
LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回0。如果给定的值或者匹配条件为NULL,则返回结果为NULL。
SELECT last_name
FROM employees
WHERE last_name LIKE '%a%e%';
_ 代表一个不确定的字符
SELECT last_name
FROM employees
转义字符: \
如果使用\表示转义,要省略ESCAPE。如果不是\,则要加上ESCAPE。
WHERE last_name LIKE '_$_a%' ESCAPE '$';
REGEXP运算符
(1)‘^’匹配以该字符后面的字符开头的字符串。 (2)‘$’匹配以该字符前面的字符结尾的字符串。 (3)‘.’匹配任何一个单字符。 (4)“[…]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”或“b”或“c”。为了命名字符的范围,使用一 个‘-’。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。 (5)‘’匹配零个或多个在它前面的字符。例如,“x”匹配任何数量的‘x’字符,“[0-9]”匹配任何数量的数字, 而“”匹配任何数量的任何字符。
SELECT 'shkstart' REGEXP '^s', 'shkstart' REGEXP 't$', 'shkstart' REGEXP 'hk';
SELECT 'abaabsf' REGEXP 'ba.bs', 'atguigu' REGEXP '[ab]';
逻辑运算符(&& ,II, !, XOR)
SELECT last_name,salary,department_id
FROM employees
WHERE department_id = 10 OR salary > 6000;
SELECT last_name,salary,department_id
FROM employees
WHERE NOT commission_pct <=> NULL;
SELECT last_name,salary,department_id
FROM employees
WHERE department_id = 50 XOR salary > 6000;
位运算符
& | ^ ~ >> <<
多表查询
SELECT employee_id,department_name
FROM employees,departments
WHERE employees.`department_id`=departments.`department_id`
SELECT employees.employee_id,departments.department_name,employees.department_id
FROM employees,departments
WHERE employees.`department_id`=departments.`department_id`
SELECT ep.employee_id,dp.department_name,ep.department_id
FROM employees ep,departments dp
WHERE ep.`department_id`=dp.`department_id`
SELECT e.last_name,e.salary,j.grade_level
FROM employees e,job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;
SELECT ep.employee_id,dp.department_name,ep.department_id
FROM employees ep,departments dp
WHERE ep.`department_id`=dp.`department_id`
SELECT ep.employee_id,dp.department_name,ep.department_id
FROM employees ep,departments dp
SELECT ep.`last_name`,dp.`department_name`,l.`city`
FROM employees ep INNER JOIN departments dp
ON ep.`department_id`=dp.`department_id`
JOIN locations l
ON dp.`location_id`=l.`location_id`;
SELECT ep.`last_name`,dp.`department_name`
FROM employees ep LEFT JOIN departments dp
ON ep.`department_id`=dp.`department_id`
SELECT ep.`last_name`,dp.`department_name`
FROM employees ep RIGHT JOIN departments dp
ON ep.`department_id`=dp.`department_id`
SELECT ep.`employee_id`,ep.`last_name`,dp.`department_name`
FROM employees ep JOIN departments dp
ON ep.`department_id`=dp.`department_id`
AND ep.`manager_id`=dp.`manager_id`;
SELECT ep.`employee_id`,ep.`last_name`,dp.`department_name`
FROM employees ep NATURAL JOIN departments dp;
SELECT ep.`employee_id`,ep.`last_name`,dp.`department_name`
FROM employees ep JOIN departments dp
USING(department_id);
聚合函数
SELECT AVG(salary)
FROM employees;
SELECT SUM(salary)
FROM employees;
SELECT COUNT(salary)
FROM employees;
SELECT AVG(commission_pct),SUM(commission_pct)/COUNT(commission_pct)
FROM employees;
SELECT department_id , AVG(salary)
FROM employees
GROUP BY department_id
SELECT department_id , job_id ,AVG(salary)
FROM employees
GROUP BY department_id , job_id;
SELECT job_id,department_id,salary
FROM employees
WHERE salary>6000
GROUP BY job_id,department_id
ORDER BY salary DESC
LIMIT 0,10
SELECT department_id,AVG(salary)
FROM employees
GROUP BY department_id WITH ROLLUP;
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000
SELECT department_id,MAX(salary)
FROM employees
WHERE department_id IN(10,20,30,40)
GROUP BY department_id
HAVING MAX(salary)>10000;
SELECT department_id,MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000 AND department_id IN(10,20,30,40);
子查询
SELECT
last_name,
salary
FROM
employees
WHERE salary >
(SELECT
salary
FROM
employees
WHERE last_name = 'Abel');
创建和管理表
CREATE DATABASE mytest1;
SHOW CREATE DATABASE mytest1;
CREATE DATABASE mytest2 CHARACTER SET 'gbk';
SHOW VARIABLES LIKE 'CHARACTER_%';
CREATE DATABASE IF NOT EXISTS mytest2 CHARACTER SET 'utf8';
CREATE DATABASE IF NOT EXISTS mytest3 CHARACTER SET 'utf8';
SHOW DATABASES;
USE atguigudb;
SHOW TABLES;
SELECT DATABASE() FROM DUAL;
SHOW TABLES FROM atguigudb;
ALTER DATABASE mytest2 CHARACTER SET 'utf8';
SHOW CREATE DATABASE mytest2;
DROP DATABASE mytest1;
DROP DATABASE IF EXISTS mytest1;
USE atguigudb;
SHOW CREATE DATABASE atguigudb;
CREATE TABLE IF NOT EXISTS myemp1(
id INT,
emp_name VARCHAR(15),
hire_date DATE
);
DESC myemp1;
SHOW CREATE TABLE myemp1;
CREATE TABLE myemp2
AS
SELECT employee_id,last_name,salary
FROM employees;
DESC myemp2;
SELECT *
FROM myemp2;
CREATE TABLE myemp3
AS
SELECT e.employee_id 'em',e.last_name 'ln',d.department_name
FROM employees e JOIN departments d
ON e.department_id=d.department_id;
DESC myemp3;
SELECT *
FROM myemp3;
CREATE TABLE employees_blank
AS
SELECT *
FROM employees
WHERE 1=2;
DESC employees_blank;
SELECT *
FROM employees_blank;
DESC myemp1;
ALTER TABLE myemp1
ADD salary DOUBLE(10,2);
ALTER TABLE myemp1
ADD phone_number VARCHAR(20) FIRST;
ALTER TABLE myemp1
ADD email VARCHAR(45) AFTER emp_name;
DESC myemp1;
SELECT *
FROM myemp1;
ALTER TABLE myemp1
MODIFY emp_name VARCHAR(35) DEFAULT 'aaa';
DESC myemp1;
ALTER TABLE myemp1
CHANGE email my_email VARCHAR(50)
ALTER TABLE myemp1
DROP COLUMN my_emil;
RENAME TABLE myemp1
TO myemp11;
DESC myemp11;
ALTER TABLE myemp2
RENAME TO myemp12;
DESC myemp12;
DROP TABLE IF EXISTS myemp12;
SELECT * FROM employees_copy;
TRUNCATE TABLE employees_copy;
SELECT * FROM employees_copy;
数据处理之增删改
USE atguigudb
SELECT DATABASE() FROM DUAL;
CREATE TABLE IF NOT EXISTS emp1(
id INT,
`name` VARCHAR(15),
hire_date DATE,
salary DOUBLE(10,2)
);
DESC emp1;
SELECT *
FROM emp1;
INSERT INTO emp1
VALUES(1,'Tom','2000-12-21',3400);
INSERT INTO emp1(id,hire_date,salary,`name`)
VALUES(2,'1999-09-09',4000,'Jerry');
INSERT INTO emp1(id ,`name`,salary)
VALUES
(4,'Jim',5000),
(5,'张俊杰',5500);
SELECT *
FROM emp1;
INSERT INTO emp1(id,`name`,salary,hire_date)
SELECT employee_id,last_name,salary,hire_date
FROM employees
WHERE department_id IN(60,70)
UPDATE emp1
SET hire_date=CURDATE()
WHERE id=5;
UPDATE emp1
SET hire_date=CURDATE(),salary=6000
WHERE id=5;
DELETE FROM emp1
WHERE id=1;
USE atguigudb
CREATE TABLE test1(
a INT,
b INT,
c INT GENERATED ALWAYS AS (a+b) VIRTUAL
);
INSERT INTO test1(a,b)
VALUES(10,20);
SELECT *
FROM test1;
排序与分页
SELECT employee_id,last_name,salary
FROM employees
ORDER BY salary;
SELECT employee_id,last_name,salary*12 AS "ss"
FROM employees
ORDER BY ss ASC;
SELECT employee_id,last_name,salary,salary*12 AS "ss"
FROM employees
WHERE salary>6000
ORDER BY ss ASC;
SELECT department_id,salary
FROM employees
ORDER BY department_id DESC , salary ASC;
SELECT employee_id , last_name
FROM employees
LIMIT 0,20;
SELECT employee_id , last_name
FROM employees
LIMIT 20,20;
SELECT employee_id , last_name
FROM employees
LIMIT 40,20;
SELECT employee_id , last_name,salary
FROM employees
WHERE salary>6000
ORDER BY salary DESC
LIMIT 20;
SELECT employee_id , last_name
FROM employees
LIMIT 2 OFFSET 20;
约束返回结果的数量可以 减少数据表的网络传输量 ,也可以 提升查询效率 。如果我们知道返回结果只有 1 条,就可以使用 LIMIT 1 ,告诉 SELECT 语句只需要返回一条记录即可。这样的好处就是 SELECT 不需 要扫描完整的表,只需要检索到一条符合条件的记录即可返回。
MySQL数据类型
CREATE DATABASE IF NOT EXISTS dbtest12 CHARACTER SET 'utf8';
SHOW CREATE DATABASE dbtest12;
CREATE TABLE temp(
id INT
) CHARACTER SET 'utf8';
SHOW CREATE TABLE temp;
CREATE TABLE temp1(
id INT,
`name` VARCHAR(15) CHARACTER SET 'gbk'
);
SHOW CREATE TABLE temp1;
DESC temp1;
CREATE TABLE temp2(
f1 INT UNSIGNED,
f2 INT,
f3 INT(5) ZEROFILL
)
INSERT INTO temp2(f3)
VALUES (123),(123456789);
SELECT *
FROM temp2;
123 123 123)123
CREATE TABLE test_year(
f1 YEAR,
f2 YEAR(4)
);
DESC test_year;
INSERT INTO test_year(f1)
VALUES('2021'),(2020);
SELECT *
FROM test_year;
CREATE TABLE test_time1(
f1 TIME
);
INSERT INTO test_time1
VALUES('2 12:30:29'), ('12:35:29'), ('12:40'), ('2 12:40'),('1 05'), ('45');
INSERT INTO test_time1
VALUES ('123520'), (124011),(1210);
INSERT INTO test_time1
VALUES (NOW()), (CURRENT_TIME());
SELECT * FROM test_time1;
CREATE TABLE test_datetime1(
dt DATETIME
);
INSERT INTO test_datetime1
VALUES ('2021-01-01 06:50:30'), ('20210101065030');
INSERT INTO test_datetime1
VALUES ('99-01-01 00:00:00'), ('990101000000'), ('20-01-01 00:00:00'), ('200101000000');
INSERT INTO test_datetime1
VALUES (20200101000000), (200101000000), (19990101000000), (990101000000);
INSERT INTO test_datetime1
VALUES (CURRENT_TIMESTAMP()), (NOW());
SELECT *
FROM test_datetime1;
CREATE TABLE test_enum(
season ENUM('春','夏','秋','冬','unknow')
);
INSERT INTO test_enum
VALUES('UNKNOW');
INSERT INTO test_enum
VALUES('1'),(3);
INSERT INTO test_enum
VALUES('ab');
INSERT INTO test_enum
VALUES(NULL);
SELECT *
FROM test_enum;
CREATE TABLE test_set(
s SET ('A', 'B', 'C')
);
INSERT INTO test_set (s)
VALUES ('A'), ('A,B');
INSERT INTO test_set (s)
VALUES ('A,B,C,A');
INSERT INTO test_set (s)
VALUES ('A,B,C,D');
SELECT *
FROM test_set;
CREATE TABLE test_binary1(
f1 BINARY,
f2 BINARY(3),
f4 VARBINARY(10)
);
CREATE TABLE test_blob1(
id INT, img MEDIUMBLOB
);
CREATE TABLE test_json(
js JSON
);
INSERT INTO test_json (js)
VALUES ('{"name":"songhk", "age":18, "address":{"province":"beijing", "city":"beijing"}}');
SELECT *
FROM test_json;
视图
CREATE DATABASE dbtest14;
USE dbtest14;
CREATE TABLE emps
AS
SELECT *
FROM `atguigudb`.employees;
CREATE TABLE depts
AS
SELECT *
FROM `atguigudb`.departments;
SELECT *
FROM emps;
SELECT *
FROM depts;
CREATE VIEW vu_emp1
AS
SELECT employee_id,last_name,salary
FROM emps;
SELECT *
FROM vu_emp1;
CREATE VIEW ve2
AS
SELECT employee_id ei, last_name lan,salary
FROM emps
WHERE salary > 8000;
SELECT *
FROM ve2;
CREATE VIEW ve3(ei,lan,sa)
AS
SELECT employee_id ei, last_name lan,salary
FROM emps
WHERE salary > 8000;
SELECT *
FROM ve3;
CREATE VIEW ved
AS
SELECT CONCAT(e.last_name,'(',d.department_name,')') ed
FROM emps e JOIN depts d
ON e.department_id=d.department_id;
SELECT *
FROM ved;
CREATE VIEW ved2
AS
SELECT employee_id,last_name
FROM vu_emp1
SELECT *
FROM ved2;
SHOW TABLES;
DESCRIBE vu_emp1;
SHOW TABLE STATUS LIKE 'vu_emp1';
SHOW CREATE VIEW vu_emp1;
CREATE OR REPLACE VIEW vu_emp1
AS
SELECT employee_id,last_name,salary,email
FROM emps
WHERE salary>7000;
DESC vu_emp1;
存储过程与存储函数
CREATE DATABASE dbtest15;
USE dbtest15;
CREATE TABLE employees
AS
SELECT *
FROM atguigudb.`employees`;
CREATE TABLE departments
AS
SELECT *
FROM atguigudb.`departments`;
SELECT *
FROM employees;
SELECT *
FROM departments;
DELIMITER $
CREATE PROCEDURE select_all_data()
BEGIN
SELECT *
FROM employees;
END $
DELIMITER ;
CALL select_all_data();
DELIMITER
CREATE PROCEDURE avg_employee_salary()
BEGIN
SELECT AVG(salary)
FROM employees;
END
DELIMITER ;
CALL avg_employee_salary()
DELIMITER
CREATE PROCEDURE show_max_salary()
BEGIN
SELECT MAX(salary)
FROM employees;
END
DELIMITER
CALL show_max_salary()
DESC employees;
DELIMITER
CREATE PROCEDURE show_min_salary(OUT ms DOUBLE)
BEGIN
SELECT MIN(salary) INTO ms
FROM employees;
END
DELIMITER ;
CALL show_min_salary(@ms);
SELECT @ms;
DELIMITER
CREATE PROCEDURE show_someone_salary (IN empname VARCHAR (20))
BEGIN
SELECT
salary
FROM
employees
WHERE last_name = empname;
END
DELIMITER ;
CALL show_someone_salary('Abel');
SET @empname := 'Abel';
CALL show_someone_salary(@empname);
DELIMITER
CREATE PROCEDURE
DELIMITER
CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(25))
BEGIN
SELECT last_name INTO empname
FROM employees
WHERE employee_id=(
SELECT manager_id
FROM employees
WHERE last_name=empname
);
END
DELIMITER ;
SET @empname='Abel';
CALL show_mgr_name(@empname);
SELECT @empname;
DELIMITER
CREATE FUNCTION email_by_name()
RETURNS VARCHAR(25)
DETERMINISTIC
CONTAINS SQL
READS SQL DATA
BEGIN
RETURN (SELECT email FROM employees WHERE last_name='Abel');
END
DELIMITER ;
SELECT email_by_name();
SET GLOBAL log_bin_trust_function_creators = 1;
DELIMITER
CREATE FUNCTION mail_by_id(emp_id INT)
RETURNS VARCHAR(25)
BEGIN
RETURN (SELECT email FROM employees WHERE employee_id=emp_id);
END
DELIMITER ;
SELECT mail_by_id(100);
DELIMITER
CREATE FUNCTION count_by_id(dept_id INT)
RETURNS INT
BEGIN
RETURN (SELECT COUNT(*) FROM employees WHERE department_id = dept_id);
END
DELIMITER ;
SELECT count_by_id(30);
SET @abc=50;
SELECT count_by_id(@abc);
SHOW CREATE PROCEDURE show_mgr_name;
SHOW CREATE FUNCTION count_by_id;
SHOW PROCEDURE STATUS;
SHOW FUNCTION STATUS;
DROP FUNCTION count_by_id;
DROP PROCEDURE show_min_salary;
变量、流程控制与游标
SHOW GLOBAL VARIABLES;
SHOW SESSION VARIABLES;
SHOW VARIABLES;
SHOW GLOBAL VARIABLES LIKE 'admin_%';
SHOW VARIABLES LIKE 'character_%';
SELECT @@global.max_connections;
SELECT @@global.character_set_client;
SELECT @@session.character_set_client;
SELECT @@character_set_client;
SET @@global.max_connections=161;
SET GLOBAL max_connections = 171;
SET @@session.character_set_client='gbk';
SET SESSION character_set_client='gbk';
CREATE DATABASE dbtest16;
USE dbtest16;
CREATE TABLE employees
AS
SELECT * FROM atguigudb.`employees`;
CREATE TABLE departments
AS
SELECT * FROM atguigudb.`departments`;
SET @m1=1;
SET @m2=2;
SET @m3=@m1+@m2;
SELECT @m3;
SELECT @count :=COUNT(*) FROM employees;
SELECT @count;
SELECT AVG(salary) INTO @sa FROM employees;
SELECT @sa;
DELIMITER
CREATE PROCEDURE hhhh()
BEGIN
DECLARE a INT DEFAULT 0;
DECLARE b INT ;
DECLARE emp_name VARCHAR(25);
SET a=1;
SET b:=2;
SELECT last_name INTO emp_name FROM employees WHERE employee_id=101;
SELECT a,b,emp_name;
END
DELIMITER ;
CALL hhhh();
DELIMITER
CREATE PROCEDURE UpdateDataNoCondition()
BEGIN
SET @x = 1;
UPDATE employees SET email = NULL WHERE last_name = 'Abel';
SET @x = 2; UPDATE employees
SET email = 'aabbel' WHERE last_name = 'Abel';
SET @x = 3;
END
DELIMITER ;
DROP PROCEDURE UpdateDataNoCondition;
CALL UpdateDataNoCondition();
DECLARE Field_Not_Be_NULL CONDITION FOR 1048;
DECLARE Field_Not_Be_NULL CONDITION FOR SQLSTATE '23000';
DELIMITER
CREATE PROCEDURE UpdateDataNoConditio()
BEGIN
DECLARE CONTINUE HANDLER FOR 1048 SET @proc_value = -1;
SET @x = 1;
UPDATE employees SET email = NULL WHERE last_name = 'Abel';
SET @x = 2;
UPDATE employees SET email = 'aabbel' WHERE last_name = 'Abel';
SET @x = 3; END
DELIMITER ;
CALL UpdateDataNoConditio();
SELECT @x;
DELIMITER
CREATE PROCEDURE aif()
BEGIN
DECLARE aif VARCHAR(15);
IF aif IS NULL
THEN SELECT 'a is null';
END IF;
END
DELIMITER ;
CALL aif();
DELIMITER
CREATE PROCEDURE haa()
BEGIN
DECLARE a INT DEFAULT 1;
loop_bl :LOOP
SET a = a + 1;
IF a>=10 THEN LEAVE loop_bl;
END IF;
END LOOP loop_bl;
SELECT a;
END
DELIMITER ;
CALL ha();
DELIMITER
CREATE PROCEDURE aa()
BEGIN
DECLARE a INT DEFAULT 1;
WHILE a<=10 DO
SET a=a+1;
END WHILE;
SELECT a;
END
CALL aa();
DELIMITER
CREATE PROCEDURE test_repeat ()
BEGIN
DECLARE i INT DEFAULT 0;
REPEAT
SET i = i + 1;
UNTIL i >= 10
END REPEAT;
SELECT i;
END
DELIMITER ;
CALL test_repeat();
DELIMITER
CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,OUT total_count INT)
BEGIN
DECLARE sum_salary DOUBLE DEFAULT 0;
DECLARE cursor_salary DOUBLE DEFAULT 0;
DECLARE emp_count INT DEFAULT 0;
DECLARE emp_cursor CURSOR FOR SELECT salary FROM employees ORDER BY salary DESC;
OPEN emp_cursor;
REPEAT
FETCH emp_cursor INTO cursor_salary;
SET sum_salary = sum_salary + cursor_salary;
SET emp_count = emp_count + 1;
UNTIL sum_salary >= limit_total_salary
END REPEAT;
SET total_count = emp_count;
CLOSE emp_cursor;
END
DELIMITER ;
CALL get_count_by_limit_total_salary(200000,@t);
SELECT @t;
SET GLOBAL MAX_EXECUTION_TIME=2000;
触发器
CREATE TABLE test_trigger (
id INT PRIMARY KEY AUTO_INCREMENT,
t_note VARCHAR(30)
);
CREATE TABLE test_trigger_log (
id INT PRIMARY KEY AUTO_INCREMENT,
t_log VARCHAR(30)
);
DELIMITER
CREATE TRIGGER before_insert
BEFORE INSERT ON test_trigger
FOR EACH ROW
BEGIN
INSERT INTO test_trigger_log (t_log)
VALUES('aaa');
END
DELIMITER ;
INSERT INTO test_trigger_log (t_log)
VALUES ('bbb');
SELECT *
FROM test_trigger;
SELECT *
FROM test_trigger_log;
SHOW TRIGGERS;
方式2:查看当前数据库中某个触发器的定义
SHOW CREATE TRIGGER 触发器名
SELECT * FROM information_schema.TRIGGERS;
DROP TRIGGER IF EXISTS 触发器名称;
|