用户变量: 在用户变量前加@
系统变量: 在系统变量前加@@
mysql中包含了100多个内置函数: https://i.cnblogs.com/EditPosts.aspx?opt=1
| 操作对象 | 操作方式 | |||
|---|---|---|---|---|
| 创建 | 删除 | 修改 | ||
| SQL | 模式 | CTREATE SCHEMA语句 | DROP SCHEMA语句 | |
| 表 | CREATE TABLE语句 | DROP TABLE语句 | ALTER TABLE语句 | |
| 视图 | CREATE VIEW 语句 | DROP VIEW 语句 | ||
| mysql增加的 | 模式 | ALTER SCHEMA | ||
| 模式 | ||||
| 视图 | ALTER VIEW | |||
CREATE {DATABASE|SCHEMA}[IF NOT EXISTS] dbI_name # [] 表示可选, | (或)用于分隔花括号中的选择项 , db_name 数据库名
, ISNOT EXISTS 表示待命名的数据库不存在才会创建
[DEFAULT]CHARACTRER SET [=] charse_name # DEFAULT用于指定默认值, CHARACTER SET 用于指定字符集
|[DEFAULT] COLLATE[=] collation_name #COLLATE用于指定字符集的小队规则
Integer rs = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS mysql_test DEFAULT CHARACTER SET = utf8");
//结果集, executeQuery()执行select语句 返回结果在result里
选择数据库
Integer rs = stmt.executeUpdate("USE db_name");
ALTER DATABASE或ALTER SCHEMA修改数据库相关参数,其语法简略为
ALTER {DATABASE|SCHEMA} [db_name]
alter_specification...
示例:
Integer rs = stmt.executeUpdate("ALTER DATABASE mysql_test DEFAULT CHARACTER SET gb2312"
+ " DEFAULT COLLATE gb2312_chinese_ci");
DROP DATABASE 和 DROP SCHEMA 删除数据库 //数据无价,操作需谨慎
DROP {DATABASE|SCHEMA} [IF EXISTS] db_name
Integer rs = stmt.executeUpdate("DROP DATABASE IF EXISTS mysql_test1");
SHOW {DATABASES 和SHOW SCHEMAS} {LIKE 'pattern'| WHERE expr}
ResultSet rs1 = stmt.executeQuery("SHOW DATABASES");
CREATE TABLE语句创建表,基本格式是
CREATE [TEMPORARY] TABLE tbl_name ( 字段1 数据类型 [列级完整性约束条件] [默认值] [, 字段2 数据类型 [列级完整约束条件][默认值]] [,......] [,表级完整约束条件] )(ENGINE=引擎类型)
USE mysql_test; CREATE TABLE customers ( cust_id INT NOT NULL AUTO_INCREMENT, #INCREMENT 可以为表中的数据类型为整形的列设置自增型 cust_name CHAR() NOT NULL, #不允许null值的列 cust_set CHAR() NOT NULL DEFAULT , #不允许null值的列且默认值是0 cust_address CHAR() NULL, cust_contact CHAR() NULL, PRIMARY KEY(cust_id) #设置cust_id 为主键 );
mysql> CREATE TABLE cus LIKE customer; Query OK, rows affected (0.73 sec)
mysql> CREATE TABLE cus1 AS SELECT * FROM customer; Query OK, rows affected (0.73 sec) Records: Duplicates: Warnings:
mysql> ALTER TABLE mysql_test.customers #改变表sustomers 增加(add) 列(column) cust_city 字符型(长度10)
-> ADD COLUMN cust_city char() NOT NULL DEFAULT 'Wuhan' AFTER cust_set;#不能为null 默认值为武汉 且位于 cust_set列之后
Query OK, rows affected (1.55 sec)
mysql> ALTER TABLE mysql_test.customers ADD INDEX index1(sex1); //为列sex1增加索引index1
Query OK, 0 rows affected (0.57 sec)
mysql> ALTER TABLE mysql_test.cust ADD FOREIGN KEY(cust_address) REFERENCES customers(sex1);#为表cust的列cust_address添加外键 参考 表customers 的列sex1
Query OK, 0 rows affected (1.55 sec)
mysql> ALTER TABLE mysql_test.customers #将表customers 的列cust_set名改为sex 数据类型改为char()
-> CHANGE COLUMN sex sex1 char() NULL DEFAULT 'M';#可以为null 默认值为m
Query OK, rows affected (0.21 sec)#需要注意不兼容数据类型不可以转换,兼容但长度不一样的数据类型,数据可能会被截断
mysql> ALTER TABLE mysql_test.customers #修改(alter)cust omers 的列 cust_city 的默认值(default)设置(set)为bj;
-> ALTER COLUMN cust_city SET DEFAULT 'bj';
Query OK, rows affected (0.14 sec)
mysql> ALTER TABLE mysql_test.customers #moddify(修改) 列 cust_name 类型为char() ,位置改为 sex1后面
-> MODIFY COLUMN cust_name char() AFTER sex1;
Query OK, rows affected (1.80 sec)
mysql> ALTER TABLE mysql_test.customers DROP COLUMN cust_name;#删除列cust_name Query OK, rows affected (1.19 sec)
mysql> ALTER TABLE mysql_test.cust RENAME TO mysql_test.cus;#将cust更名为cus Query OK, rows affected (0.40 sec)
RENAME TABLE tbl_name TO new_tbl_name [tb2_name TO new_tb2_name] #rename可以批量重命名表
mysql> RENAME TABLE mysql_test.cu TO mysql_test.cus, mysql_test.customers TO customer; Query OK, rows affected (0.70 sec)
语法格式
DROP[TEMPORARY]TABLE[IF EXISTS]
tb1_name[,tb2_name] ... #
restrict: 确保只有不存在相关视图和 完整性约束的表才能删除
[RESTRICT][CASCADE] #在删除一个表时,如果该表的主键是另一个表的外键,如果不用cascade关键字就会报错
mysql> DROP TABLE IF EXISTS mysql_test.cus CASCADE;#删除表cus 使用CASCADE删除完整性约束 Query OK, rows affected (0.41 sec)
SHOW [FULL] TABLES [{FROM|IN} db_name] [LIKE 'pattern' [WHERE expr]
mysql> SHOW TABLES FROM gc LIKE 'b%s'; +--------------------+ | Tables_in_gc (b%s) | +--------------------+ | books | +--------------------+ row in set (0.00 sec)
SHOW [FULL] COLUMNS {FROM|IN} tbl_name [{FROM|IN} db_name] [LIKE 'pattern'| WHERE expr]
DESCRIBE tbl_name;
mysql> SHOW COLUMNS FROM mysql_test.customer LIKE 's%1'; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | sex1 | char() | YES | MUL | M | | +-------+---------+------+-----+---------+-------+ mysql> describe mysql_test.customer; +--------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+----------+------+-----+---------+----------------+ | cust_id | int() | NO | PRI | NULL | auto_increment | | sex1 | char() | YES | MUL | M | | | cust_address | char() | YES | | NULL | | | cust_contact | char() | YES | | NULL | | +--------------+----------+------+-----+---------+----------------+ rows in set (0.00 sec)
1.普通索引(index) 最基本的索引,没有任何限制,通常使用关键字INDEX或KEY
2.唯一索引(unique) 和普通索引基本相同,只是有一点区别,即索引列中的所有值都只能出现一次,必须是唯一的,通常使用关键字UNIQUE
3.主键 PRIMARY KEY 主键是一种唯一索引,不能为控制,每个表只能有一个主键
1.使用CREATE INDEX语句创建
CREATE [UNIQUE] INDEX index_name ON tb1_name(index_col_name,...)
#col_name用于指定要创建索引的列名,通常可考虑WHERE和JOIN子句里出现的列来作为索引列
其中,index_col_name的格式为
col_name[(length)][ASC|DESC] #asc升序 desc降序 默认asc , length用于指定前length个字符来创建索引
示例1:根据用户地址address的前3个字符建立索引
mysql> CREATE INDEX index_customers ON mysql_test.cus1(cust_address() DESC); Query OK, rows affected (0.48 sec)
示例2: 根据用户地址和ID创建一个组合索引
mysql> CREATE INDEX index_cust ON mysql_test.cus1(cust_address() DESC,cust_id); Query OK, rows affected (0.56 sec)
2. 使用CREATE TABLE语句创建索引
i) 语法项[CONSTRAINT [symbol]] PRIMARY KEY (index_col_name,.....),用于表示在创建新表的同时创建该表的索引
ii) 语法项{INDEX|KE} [index_name] (index_col_name,...), 用于表示创建新表的同时创建该表的索引
iii) 语法项[CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] (index_col_name,...),用于表示在创建新表的同时创建该表的唯一性索引
iv) 语法项[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,......), 用于表示在创建新表的同时创建该表的外键
其中关键字KEY 时INDEX的同义字, CONSTRAINT 用于为主键,外键,UNIQUE键定义一个名字.
示例:
CREATE TABLE seller ( seller_id int NOT NULL AUTO_INCREMENT, seller_name char() NOT NULL, seller_address char() NULL, seller_contact char() NULL, product_type int() not NULL, sales int NULL, CONSTRAINT a_key PRIMARY KEY(seller_id,product_type), INDEX index_seller(sales) );
3.)使用ALTER TABLE语句创建索引
i) 语法项 ADD {INDEX|KE} [index_name] (index_col_name,...), 用于表示修改表的同时为该表的添加索引
ii) 语法项[CONSTRAINT [symbol]] PRIMARY KEY (index_col_name,.....),用于表示修改表的同时为该表的添加索引
iii) 语法项[CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] (index_col_name,...),用于表示修改表的同时为该表的添加唯一性索引
iv) 语法项[CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,......), 用于表示在修改表的同时为该表的添加外键
示例:在表seller的姓名列上添加一个非唯一索引
mysql> ALTER TABLE mysql_test.seller ADD INDEX index_seller_name(seller_name); Query OK, rows affected (0.40 sec) Records: Duplicates: Warnings:
mysql> ALTER TABLE mysql_test.seller1 ADD CONSTRAINT f_key FOREIGN KEY index_customers(seller_name) REFERENCES mysql_test.seller(seller_name); Query OK, rows affected (1.32 sec) #注意设置外键时另一个表必须有一个相同的属性,并且设置了索引 Records: Duplicates: Warnings:
SHOW {INDEX][INDEXES|KEYSK}
{FROM | IN} tbl_name
[{FROM | IN} db_name}
WHERE expr;
mysql> SHOW INDEXES FROM seller FROM mysql_test; +--------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression | +--------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ | seller | | PRIMARY | | seller_id | A | | NULL | NULL | | BTREE | | | YES | NULL | | seller | | PRIMARY | | product_type | A | | NULL | NULL | | BTREE | | | YES | NULL | | seller | | index_seller | | sales | A | | NULL | NULL | YES | BTREE | | | YES | NULL | | seller | | index_seller_name | | seller_name | A | | NULL | NULL | | BTREE | | | YES | NULL | +--------+------------+-------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+ rows in set (0.18 sec)
mysql>show create table 表名 //此方法可以列除所有约束
1.使用DROP INDEX语句删除索引
DROP INDEX index_name ON tb1_name
mysql> DROP INDEX index_seller ON mysql_test.seller; Query OK, rows affected (0.30 sec) Records: Duplicates: Warnings:
2.使用ALTER TABLE 语句删除索引
i) 选用DROP PRIMARY KEY 子句用于删除表中的主键,由于一个表中只有一个主键,其也是一个索引
ii) 选用DROP INDEX子句用于删除各种类型的索引
iii) 选用DROP FOREIGN KEY 子句用于删除外键
mysql> alter table seller1 drop INDEX index_seller_name;
Query OK, 0 rows affected (0.35 sec)
INSERT[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE } (expr | DEFAULT},...),(...),...
i) 对应IDENTITY属性的列,系统会自动生成序号值来唯一表示该列
ii)AUTO_INCREMENT属性列的值,在其它类被复制后自动生成
iii)对于TIMESTAMP的列系统会自动赋值
mysql> INSERT INTO mysql_test.customer(cust_id,sex1,cust_address,cust_contact) VALUES(,'李','武汉市',NULL); Query OK, row affected (0.09 sec)
INSERT [INTO] tb1_name
SET col_name={expr | DEFAULT},...
mysql> INSERT INTO mysql_test.customer SET cust_contact=DEFAULT,cust_address='武汉市',sex1=DEFAULT; Query OK, row affected (0.09 sec)
INSERT [INTO] tbl_name [(col_name,..)] SELECT ...;
mysql> INSERT INTO mysql_test.customer(cust_address) SELECT cust_contact FROM mysql_test.customer WHERE cust_contact IS NOT NULL; Query OK, rows affected (0.14 sec) Records: Duplicates: Warnings:
在mysql中可以用DELETE语句删除一行或多行数据
DELETE FROM tbl_name
[WHERE where_condition]
[ORDER BY...] #表示更好将按照ORDER BY子句指定的顺序删除
[LIMIT row_count] #用于告知服务器在控制命令返回到客户端前被删除的行最大值
mysql> DELETE FROM mysql_test.customer WHERE cust_id < ORDER BY cust_id LIMIT ; Query OK, rows affected (0.00 sec)
在mysql中可以用UPDATE语句修改更新一个表中的数据,实现对表中行的列数据进行修改,其语法格式是
UPDATE tbl_name #tb1_name 表名
SET col_name1={expr|DEFAULT} [,col_name2={expr2|DEAULT}] ... #SET子句用于知道要修改的列名集其列值
[WHERE where_condition]
[ORDER BY ..]
[LIMIT row_count]
mysql> UPDATE mysql_test.customer SET cust_contact = '武汉' WHERE cust_contact IS NULL ORDER BY cust_id DESC LIMIT ; Query OK, rows affected (0.11 sec) #对表customer 的列cust_contact赋值,从cust_id的反序倒数的20个 Rows matched: Changed: Warnings:
一.SELECT 语句常用语法格式
SELECT
[ALL | DISTINCT | DISTINCTROW] # 此三个参数用于消除结果集中的重复行, 当指定了后,对所有查询结果生效
select_expr [,select_expr ...]
FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position} # GROUP BY对检索到的结果分组
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition] # HAVING 用于指定组的过滤条件
[ORDER BY {col_name | expr | position} # ORDER BY 对查询结果排序
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}] #LIMIT 要检索的函数
| 子句 | 说明 | 是否必须使用 |
| SELECT | 要返回的列或表达式 | 是 |
| FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
| WHERE | 行级过滤 | 否 |
| GROUP BY | 分组说明 | 仅在按组计算集合时使用 |
| HAVING | 组级过滤 | 否 |
| ORDER BY | 输出排序顺序 | 否 |
| LIMIT | 要检索的行数 | 否 |
示例:
mysql> SELECT DISTINCT cust_contact FROM customer WHERE cust_contact IS NOT NULL GROUP BY cust_id HAVING cust_contact = 'china' ORDER BY cust_contact DESC LIMIT ;
mysql> SELECT sex1, cust_address FROM customer WHERE sex1 > 'a' and sex1 < 'c'; +------+------------------+ | sex1 | cust_address | +------+------------------+ | b | www.feilong1.com | | b | www.feilong1.com | | b | www.feilong1.com | | b | www.feilong1.com | +------+------------------+ rows in set (0.00 sec)
格式
column_name [AS] column_alias
mysql> SELECT sex1 AS A, cust_address AS B FROM customer WHERE sex1 > 'a' and sex1 < 'c'; +------+------------------+ | A | B | +------+------------------+ | b | www.feilong1.com | | b | www.feilong1.com | | b | www.feilong1.com | | b | www.feilong1.com | +------+------------------+ rows in set (0.00 sec)
3. 替换查询结果集中的数据
格式:
CASE
WHEN 条件 THEN 表达式
WHEN 条件2 THEN 表达式
...
ELSE 表达式
END[AS] column_alias
示例:
mysql> SELECT cust_address, CASE WHEN (sex1 > 'a' AND sex1 < 'z') THEN 'male' ELSE 'woman' END AS 性别 FROM customer;#注意要加逗号 +------------------+--------+ | cust_address | 性别 | +------------------+--------+ | www.feilong1.com | male | | www.feilong1.com | male |
使用SELECT 语句对列进行查询时,在结果集中可以输出对列值计算后的值
mysql> SELECT cust_address, sex1,cust_id+ FROM mysql_test.customer WHERE sex1 < 'b'; +------------------+------+-------------+ | cust_address | sex1 | cust_id+ | +------------------+------+-------------+ | www.feilong1.com | a | | | www.feilong1.com | a | | | www.feilong1.com | a | | | www.feilong1.com | a | | +------------------+------+-------------+ rows in set (0.00 sec)
SELECT 语句的语法项 "select_expr" 也可以指定为集合函数, 集合函数通常是数据库系统中一类系统内置函数,常用于对一组值进行计算,然后返回单个值,它通常与GROUP BY 一起使用,如果SELECT 语句中有一个GROUP BY 子句,则这个聚合函数对所欲列起作用, 否则,SELECT 语句只产生一行作为结果,另外除了COUNT函数,集合函数都会忽略空值
| 函数名 | 说明 |
| COUNT | 求组中项数, 返回INT类型整数 |
| MAX | 求最大值 |
| MIN | 求最小值 |
| SUM | 求表达式中所有值的和 |
| AVG | 求组中值的平均值 |
| STD或STDDEV | 返回给定表达式中所有值的标准差 |
| VARIANCE | 返回给定表达式中所有值的方差 |
| GROUP_CONCAT | 返回由属于一组的列值连接组合而成的结果 |
| BIT_AND | 逻辑或 |
| BIR_OR | 逻辑与 |
| BIT_XOR | 逻辑异或 |
mysql> SELECT COUNT(*) FROM customer WHERE sex1 = 'a' ;#count(*):返回表中满足where条件的行的数量 +----------+ | COUNT(*) | +----------+ | | +----------+ row in set (0.00 sec)
mysql> SELECT COUNT(sex1) FROM customer;#count(列):返回列值非空的行的数量 +-------------+ | COUNT(sex1) | +-------------+ | | +-------------+ row in set (0.00 sec)
mysql> SELECT COUNT(cust_id > OR NULL) FROM customer;#④count(expr):根据表达式统计数据 OR NULL必加 +-----------------------------+ | COUNT(cust_id > OR NULL) | +-----------------------------+ | | +-----------------------------+ row in set (0.00 sec)
mysql> SELECT MAX(cust_id) FROM customer;# 求最大值 +--------------+ | MAX(cust_id) | +--------------+ | | +--------------+ row in set (0.00 sec)
语法
SLECT * FROM tbl1 CROSS JOIN tbl2 CROSS JOIN tbl3 ......;#CROSS JOIN 可以省略,当存在大量数据时慎用
示例
rows in set (0.05 sec) mysql> SELECT * FROM customer CROSS JOIN customer1;
内链接是一种最常用的连接类型,内连接是利用条件判断表达式中的比较来组合两张表的记录,其目的式为了消除交叉连接中的某些数据行
SELECT some_column #some_column用于指定需要检索的列的名称或列别名
FROM table1
INNER JOIN # INNER 可以省略
table2
ON some_conditions;
some_conditions的一般语法格式
[<table1>.]<列名或列别名><比较运算符>[<table2>.]<列名或列别名>
示例
rows in set (0.00 sec) mysql> SELECT * FROM customer A INNER JOIN customer1 B ON A.cust_id = B.cust_id;
rows in set (0.00 sec) mysql> SELECT * FROM customer A INNER JOIN customer1 B ON A.cust_id = B.cust_id;
rows in set (0.01 sec) mysql> SELECT * FROM customer A INNER JOIN customer1 B ON A.cust_id > B.cust_id + ;
外连接是首先将连接的两张表分为基表和参考表,然后再以基表为依据返回满足和不满足条件的记录
rows in set (0.01 sec) mysql> SELECT A.sex1,B.cust_address FROM customer A LEFT OUTER JOIN customer1 B ON A.sex1 = B.sex1;
rows in set (0.01 sec) mysql> SELECT A.sex1,B.cust_address FROM customer A RIGHT OUTER JOIN customer1 B ON A.sex1 = B.sex1;
当两个表达式的值均不为NULL时, 除了"<=>"运算符,其它比较运算符都返回TRUE或FALSE,而当两个表达式其中有一个为空或都为空时,则会返回UNKNOWN
rows in set (0.00 sec) mysql> SELECT A.cust_contact,B.cust_contact FROM mysql_test.customer A,mysql_test.customer1 B WHERE A.cust_id = B.cust_id;
(1)BETWEEN ... ADN
expression1 [NOT] BETWEEN expression AND expression2 #表达式expression1的值不能大于表达式expression2的值
rows in set (0.00 sec) mysql> SELECT A.cust_contact,B.cust_contact FROM mysql_test.customer A,mysql_test.customer1 B WHERE (A.cust_id BETWEEN AND ) AND (B.cust_id BETWEEN AND );
(2)IN
使用关键字"IN"可以指定一个枚举表,该表中列出所有可能的值,其语法格式为:
expression IN (expression[,...n])
mysql> SELECT A.cust_contact FROM mysql_test.customer A WHERE A.cust_id IN(SELECT cust_id FROM customer1 WHERE cust_id > ); +--------------+ | cust_contact | +--------------+ | q | | p | +--------------+ rows in set (0.00 sec)
expression IS [NOT] NULL
mysql> SELECT A.cust_contact FROM mysql_test.customer A WHERE A.cust_contact IS NULL; +--------------+ | cust_contact | +--------------+ | NULL | +--------------+ row in set (0.00 sec)
通常,可以使用SELECT 语句创建子查询,即可以嵌套再其他 SELECT 查询中的SELECT 查询
i) 表子查询
ii) 行子查询
iii) 列子查询
iv) 标量子查询 , 即子查询的结果集仅仅是一个值
(1) 结合关键字"IN"使用的子查询
expression [NOT] IN (subquery)
mysql> SELECT A.cust_contact FROM mysql_test.customer A WHERE A.cust_id IN(SELECT cust_id FROM customer1 WHERE cust_id > ); +--------------+ | cust_contact | +--------------+ | q | | p | +--------------+ rows in set (0.00 sec)
(2) 结合比较运算符使用的子查询
expression { = | < | <= | > | >= | <=> | <> | !=} {ALL | SOME| ANY}(subquery)
# ALL表示当表达式与子查询结果的每个值都满足比较关系时,会返回 TRUE 否则返回 FALSE, "SOME"和"ANY"表示当表达式与子查询结果的任何一个值满足时返回TRUE,否则返回NULL
rows in set (0.00 sec) mysql> SELECT A.cust_contact FROM mysql_test.customer A WHERE A.cust_contact = SOME(SELECT cust_contact FROM customer) ;
(3) 结合关键字"EXIST"使用的子查询
mysql> SELECT A.cust_contact FROM mysql_test.customer A WHERE NOT EXISTS
(SELECT B.cust_contact FROM mysql_test.customer1 B WHERE A.cust_contact = B.cust_contact);
五. GROUP BY 子句与分组数据
再SELECT 语句中,允许使用GROUP BY 子句,将结果集中的数据根据选择列的值进行逻辑分组,以便能汇总表内容的子集,即实现每个组的聚集计算.
GROUP BY 语法格式
GROUP BY {col_name | expr | position}[ASC | DESC], ... [WITH ROLLUP]
#col_name 指定分组的选择列,可以指定多个列,用逗号隔开
#expr 指定用于分组的表达式, 该表达式通常与集合函数一块使用,例如 COUNT(*) AS '人数'
#position 用于指定分组的选择列再SELECT语句结果集中的位置,通常时一个正整数,例如 GROUP BY 3
#WITH ROLLUP 用于指定再结果集中不仅包含GROUP BY 子句分组的数据,还包括各分组的汇总行,以及所有分组的整体汇总行,
#因此使用该关键字可以得到每个分组以及每个分组汇总级别的值
| www.feilong1.com | NULL | | | 武汉市 | 李 | | | 武汉市 | NULL | | | NULL | NULL | | +------------------+------+--------+ rows in set (0.00 sec) mysql> SELECT cust_address, sex1, COUNT(*) AS '人数' FROM mysql_test.customer
GROUP BY cust_address,sex1 WITH ROLLUP;
六 HAVING子句
HAVING子句可以过滤分组,其语法格式为:
HAVING where_condition #where_codition为过滤条件 WHERE 过滤掉的行不包含再分组中
mysql> SELECT cust_address, sex1, COUNT(*) AS '人数' FROM mysql_test.customer GROUP BY cust_address,sex1 WITH ROLLUP HAVING COUNT(*)<= ; +------------------+------+--------+ | cust_address | sex1 | 人数 | +------------------+------+--------+ | www.feilong1.com | w | | | www.feilong1.com | x | | | www.feilong1.com | y | | | www.feilong1.com | z | | | 武汉市 | 李 | | | 武汉市 | NULL | | +------------------+------+--------+ rows in set (0.00 sec)
七. ORDER BY 子句
ORDER BY 子句可以将结果集中的数据按一定的顺序排序
ORDER BY {col_name | expr | position} [ASC | DESC], ......
i) DRDER BY 子句可以包含子查询
ii) 当对空值进行查询时,ORDER BY 子句会将空值当最小值对待
iii) 在ORDER BY 子句中指定多个列进行排序,则再MySQL中会按照这些列从左至右所罗列的次序进行排序
iv) 在使用GROUP BY子句时通常也会使用ORDER BY 子句
rows in set (0.00 sec) mysql> SELECT sex1, cust_contact FROM mysql_test.customer ORDER BY sex1 DESC,cust_contact ASC;
| ORDER BY 子句 | GROUP BY 子句 |
| 排序产生输出 | 分组行,但输出可能不是分组的排序 |
| 任意列都可以使用 | 只能使用选择列或表达式 |
| 不一定需要 | 若与集合函数一起使用列或表达式,则必须使用 |
八. LIMIT 子句
LIMIT 可以限制SELECT 返回的行数
LIMIT {[offset,] rwo_count | row_count OFFSET offset}
i) offset 为可选项,默认值为0,用于指定返回数据的第一行在SELECT语句结果集中的偏移量,其必须是非负整数常量,注意,SELECT 语句结果集中第一行的偏移量为0而不是1.
ii) row_count: 用于指定返回数据的行数,其也必须是非负整数常量,若这个指定行数大于实际能返回的行数时,将返回它能返回的数据行
iii) row_count OFFSET offset: 从第offset + 1行开始, 取row_count行
mysql> SELECT sex1 FROM customer WHERE cust_id BETWEEN AND LIMIT ,; +------+ | sex1 | +------+ | n | | o | | p | | q | | r | +------+ rows in set (0.00 sec)
mysql> SELECT sex1 FROM customer WHERE cust_id BETWEEN AND LIMIT OFFSET ; +------+ | sex1 | +------+ | n | | o | +------+ rows in set (0.00 sec)
CREATEVIEW view_name [colmun_list]
AS select_statement
[WITH [ CASCADED | LOCAL | CHECK OPTION]
i) view _name 用于指定视图的名称,且该名称在数据库中必须是唯一的,不能与其他表或视图同名
ii) column_list 是可选项, 用于为视图中的每个列指定明确的名称,且列名的数目必须等于SELECT 语句检索出的结果数据集中的列数,同时每个列名之间用逗号分隔, 可以省略column_list
iii) select_statement 用于指定创建视图的SELECT语句,这个SELECT 语句给出了视图的定义,它可以查询多个基本表或源视图
iv) WITH CHECK OPTION 是可选项,用于指定在可更新视图上所进行的修改都需要符合select_statment中所指定的限制条件,这样可以确保数据修改后,仍然可以通过视图看到修改后的数据. 当视图是根据另外一个视图定义时,关键字 WITH CHECK OPTION 给出两个参数, 即 CASCADED 和local,它们决定检查测试的范围,其中, 关键字" CASCADED "为默认值,他会对所有视图进行检查,而关键字"LOCAL" 则使CHECK OPTION 只对定义的视图进行检查.
例:创建视图customer_view ,要求该视图包含所有男客户的信息,并且保证以后对该视图的修改都必须符合客户为男性这个条件
mysql> CREATE OR REPLACE VIEW customer_view AS SELECT * FROM mysql_test.customer WHERE sex1 = '男' WITH CHECK OPTION; Query OK, rows affected (0.14 sec)
DROP VIEW [IF EXISTS] view_name[,view_name] ... [RESTRICT | CASCADE]
mysql> DROP VIEW IF EXISTS customer_view CASCADE; Query OK, rows affected (0.17 sec)
ALTER VIEW view_name [(column_list)]
AS select_statement
[WITH | CASCADED | LOCAL] CHECK OPTION]
mysql> ALTER VIEW customer_view AS SELECT * FROM customer1 WHERE sex1 = '男' WITH CHECK OPTION; Query OK, rows affected (0.14 sec)
SHOW CREATE VIEW view_name
mysql> SHOW CREATE VIEW customer_view; +---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+ | View | Create View | character_set_client | collation_connection | +---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+ | customer_view | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `customer_view` AS select `customer1`.`cust_id` AS `cust_id`,`customer1`.`sex1` AS `sex1`,`customer1`.`cust_address` AS `cust_address`,`customer1`.`cust_contact` AS `cust_contact` from `customer1` where (`customer1`.`sex1` = '男') WITH CASCADED CHECK OPTION | utf8mb4 | utf8mb4_0900_ai_ci | +---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+ row in set (0.00 sec)
由于视图是一个虚拟表所以,通过插入,修改,删除等操作方式来更新视图的数据,实质上是在修改视图所引用的基本表中的数据
mysql> INSERT INTO mysql_test.customer_view VALUES(,'男','www.zm.com','武汉'); Query OK, row affected (0.11 sec)
mysql> UPDATE mysql_test.customer_view SET cust_address = '上海'; Query OK, rows affected (0.14 sec) Rows matched: Changed: Warnings:
可以如同查询数据库中的真实表一样对视图进行查询
mysql> SELECT cust_id, cust_contact FROM customer_view WHERE cust_id = AND cust_contact = '武汉'; +---------+--------------+ | cust_id | cust_contact | +---------+--------------+ | | 武汉 | +---------+--------------+ row in set (0.00 sec)
存储过程是一组为了完成某项特定功能的SQL语句集,其实质上就是一段存储在数据库中的代码,它可以由过程式的SQL语句(如CREATE , UPDATE 和SELECT等语句)和过程式SQL语句(如IF...THEN...ELSE控制结构语句)组成.
MySQL数据库SQL语句默认是以分号作为语句结束标志,可以通过DELIMITER(分隔符) 将MySQL语句的结束标志改为替他符号,
DELIMITER 语法格式:
DELIMITER $$ # $$ 为用户定义的结束符
mysql> DELIMITER $$ # $$ 为用户定义的结束符 mysql> SELECT cust_id, cust_contact FROM customer_view WHERE cust_id = AND cust_contact = '武汉'$$ +---------+--------------+ | cust_id | cust_contact | +---------+--------------+ | | 武汉 | +---------+--------------+ row in set (0.00 sec)
在MySQL 中使用CREATE PROCEDURE来创建存储过程,其语法格式是:
CREATE PROCEDURE sp_name ([proc_parameter[,...]]}
routine_body
其中,语法项proc_parameter语法格式是:
[IN | OUT | INOUT ] param_name type
i) sp_name 用于指定存储过程的名称,且默认在当前数据库创建
ii) proc_parameter 用于指定存储过程的参数列表,其中的语法项param_name 为参数名, 语法项type 为数据类型, 参数列表用逗号隔开,也可以没有参数. MySQL 存储过程支持三种类型的参数,即 输入参数. 输出参数 和输入输出参数, 分别用 "IN" "OUT" "INOUT"三个关键字标识, 需要注意参数的取名不要与数据表的列名相同.
iii) routine_body 表示存储过程的主体部分,也称为存储过程体,其包含了在过程调用的时候必须执行的SQL语句,这个部分是以关键字"BEGIN" 开始, 以关键字 "END" 结束. 如若存储过程体中只有一条SQL语句时,可以省略 BEGIN ... END 标. 另外,在存储过程体中, BEGIN...END 符号语句还可以嵌套使用
例: 在数据库 mysql_test 中创建一个存储过程, 用于实现给定表 customer 中一个客户id 号 即可修改customer中该客户的性别为指定的性别.
DROP PROCEDURE IF EXISTS sp_update_sex; Query OK, rows affected, warning (0.04 sec)
mysql> use mysql_test Database changed
DELIMITER $$
CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR(1))
BEGIN
UPDATE customer SET sex1 = csex WHERE cust_id = cid; #注意博客园的代码块的编码方式可能和mysql不一样, 如果报错,可以不要复制 用手输
END $$
mysql> DELIMITER ; $$
在存储过程体中可以声明局部变量, 用来存储存储过程体中的临时结果,在MySQL中,可以使用DECLARE 语句来声明局部变量, 并同时还可以对该局部变量赋予一个初始值,其语法格式为:
DECLARE var_name[,...] type [DEFAULT value] #var_name 变量名, type 数据类型, DEFALUT 为局部变量指定默认值
例 声明一个局部变量cid
DECLARE cid INT();
i) 局部变量只能在存储过程体的BEGIN...END语句块中声明
ii) 局部变量必须在存储过程体的开头出声明
iii) 局部变量的作用范围仅限于声明它的 BEGIN...END 语句块,
iv) 局部变量不同于用户变量,两者的区别是: 局部变量声明时, 在其前面没有使用@符号,并且它只能被声明它的BEGIN...END块使用; 而用户变量在声明时, 会在其名称前面使用@符号,同时已声明的用户变量存在于整个会话之中.
mysql> DELIMITER $$
mysql> CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR())
-> BEGIN
-> DECLARE cid INT();
-> UPDATE customer SET sex1 = csex WHERE cust_id = cid;
-> END $$
Query OK, rows affected (0.15 sec)
SET 语句为局部变量赋值,其语法格式是:
SET var_name = expr[, var_name = expr ] ...
例 为cid1局部变量赋予一个整数值100
mysql> DELIMITER $$
mysql> CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR())
-> BEGIN
-> DECLARE cid1 INT();
-> SET cid1 = ;
-> UPDATE customer SET sex1 = csex WHERE cust_id = cid1;
-> END $$
Query OK, rows affected (0.17 sec)
可以直接用SELECT ... INTO 语句把选定的值直接存储到局部变量中,其语法格式是
SELECT col_name INOT var_name[,...] table_expr
mysql> CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR())
-> BEGIN
-> DECLARE cid1 INT();
-> SELECT cust_id INTO cid1 WHERE cust_id = ;
-> UPDATE customer SET sex1 = csex WHERE cust_id = cid1;
-> END $$
Query OK, rows affected (0.15 sec)
(1) 条件判断语句
常用的有 IF...THEN...ELSE 语句和 CASE 语句 它们的用法类似于高级语言
DELIMITER $$
CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR())
BEGIN
DECLARE cid1 INT();
SELECT cust_id INTO cid1 WHERE cust_id = ;
IF cid1 >
THEN SET cid1 = ;
ELSE SET cid1 = ;
END IF;
UPDATE customer SET sex1 = csex WHERE cust_id = cid1;
END $$
(2) 循环语句
常用的有 WHILE 语句, REPEAT 语句和 LOOP语句,它们的语法类似于高级语言; 可以使用ITERATE语句退出当前循环,开始下一个循环
DELIMITER $$
CREATE PROCEDURE sp_update_sex( IN cid INT, IN csex CHAR())
BEGIN
DECLARE cid1 INT();
SELECT cust_id INTO cid1 WHERE cust_id = ;
WHILE(cid1 > ) DO
SET cid1=cid1-;
END WHILE;
IF cid1 >
THEN SET cid1 = ;
ELSE SET cid1 = ;
END IF;
UPDATE customer SET sex1 = csex WHERE cust_id = cid1;
END $$
在MySQL中,一条SELECT ... INTO 语句执行成功后会返回带有中的一行数据,这行数据可以被直接读取; 然而在使用SELECT 语句进行数据检索时,若该语句成功执行,则会返回一组称为结果集的数据行,该结果集中可能拥有多行数据,这些数据无法被一行一行的读取,这时就要使用游标.
游标时一个被SELECT语句检索出来的结果集.
(1) 声明游标
DECLARE cursor_name CURSOR FOR select_statement #cursor_name 游标名, select_staement 用于指定一个SELECT 语句,
(2)打开游标
OPEN cursor_name #在定义游标后必须打开游标才能使用
(3) 读取数据
FETCH cursor_name INTO var_name[, var_name] ....
#cursor_name 用于指定已打开的游标
#FETCH...INTO 语句与 SELECT...INTO 语句具有相同的意义,FETCH 语句时将游标指向的一行数据赋给一些变量,
这些变量的数目必须等于声明游标时SELECT 子句中选择列的数目,游标相当于一个指针,它指向当前的一行数据
(4) 关闭游标
CLOSE cursor_name # 每个游标在不需要使用时都应被关闭
DELIMITER $$ #将命令结束符改为$$
CREATE PROCEDURE sp_sumofrow (OUT ROWS1 INT) #注意变量不要用Mysql的保留字
BEGIN
DECLARE cid INT; #定义一个int变量用来接受FETCH 提取的值
DECLARE FOUND BOOLEAN DEFAULT TRUE; #定义FOUND 的值默认为true
DECLARE cur_cid CURSOR FOR #定义一个cursor(游标) 必须在所有DECLARE声明变量的语句之后
SELECT cust_id FROM customer;
DECLARE CONTINUE HANDLER FOR NOT FOUND #定义CONTINUE HANDLER 句柄,必须在游标之后
SET FOUND = FALSE;
SET ROWS1 =;
OPEN cur_cid;#打开游标
FETCH cur_cid INTO cid; #提取数据
WHILE FOUND DO
SET ROWS1 = ROWS1+;
FETCH cur_cid INTO cid;
END WHILE;
CLOSE cur_cid; #关闭游标
END $$
调用存储过程
mysql> call sp_sumofrow(@rows); Query OK, rows affected (0.00 sec)
查看调用存储过程后的结果
mysql> SELECT @rows; +-------+ | @rows | +-------+ | | +-------+ row in set (0.00 sec)
创建好的存储过程,可以在程序或其他存储过程用CALL调用
CALL sp_name([parameter[, ...]) CALL sp_name()
mysql> CALL sp_sumofrow(@rows1); Query OK, rows affected (0.00 sec) mysql> SELECT @rows1; +--------+ | @rows1 | +--------+ | | +--------+ row in set (0.00 sec)
mysql> DROP PROCEDURE IF EXISTS sp_update_sex; #注意在删除之前必须确认该存储过程没有依赖关系 Query OK, rows affected (0.14 sec)
SHOW {PROCEDURE | FUNCTION} STATUS [LIKE ‘pattern’]
mysql> SHOW PROCEDURE STATUS LIKE 'sp%' \G; #查询所有sp开头的存储过程
*************************** . row ***************************
Db: mysql_test
Name: sp_sumofrow
Type: PROCEDURE
Definer: root@%
Modified: -- ::
Created: -- ::
Security_type: DEFINER
Comment:
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
Database Collation: gb2312_chinese_ci
row in set (0.00 sec)
SHOW CREATE {PROCEDURE | FUNCTION} sp_name
mysql> SHOW CREATE PROCEDURE sp_sumofrow; +-------------+-----------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+ | Procedure | sql_mode | Create Procedure | character_set_client | collation_connection | Database Collation | +-------------+-----------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+ | sp_sumofrow | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`%` PROCEDURE `sp_sumofrow`(OUT ROWS1 INT) BEGIN DECLARE cid INT; DECLARE FOUND BOOLEAN DEFAULT TRUE; DECLARE cur_cid CURSOR FOR SELECT cust_id FROM customer; DECLARE CONTINUE HANDLER FOR NOT FOUND SET FOUND = FALSE; SET ROWS1 =; OPEN cur_cid; FETCH cur_cid INTO cid; WHILE FOUND DO SET ROWS1 = ROWS1+; FETCH cur_cid INTO cid; END WHILE; CLOSE cur_cid; END | utf8mb4 | utf8mb4_0900_ai_ci | gb2312_chinese_ci | +-------------+-----------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+ row in set (0.00 sec)
存储函数和存储过程的区别
i) 存储函数不能有输出函数,因为存储函数本身就是输出函数
ii) 可以直接对存储函数进行调用,且不需要CALL 语句,而调用存储函数要 CALL 语句
iii) 存储函数中必须包含一条RETURN 语句,而这条特殊的SQL 语句不允许包含于存储过程中
一. 创建存储函数
CREATE FUNCTION sp_name{[ func_parameter[,...]}
RETURNS TYPE
routine_body
i)func_parameter用于指定参数,这里的参数只有名称,没有关键字IN, OUT, INOUT
ii) sp_name 用于指定存储函数名,不能和存储过程重名
iii) RETURNS子句用于声明存储函数返回值的数据类型, type 用于指定返回值的数据类型
iv) routine_body 函数体, 函数体中必须包含一个RETURN value语句,其中value用于指定函数的返回值
mysql> DELIMITER $$
mysql> CREATE FUNCTION fn_search(cid INT)
-> RETURNS CHAR()
-> DETERMINISTIC
-> BEGIN
-> DECLARE SEX CHAR();
-> SELECT
-> sex1
-> INTO SEX FROM
-> customer
-> WHERE
-> cust_id = cid;
-> IF SEX IS NULL THEN
-> RETURN(SELECT 'NO such customer');
-> ELSE IF SEX = 'F' THEN
-> RETURN(SELECT 'woman');
-> ELSE RETURN ( SELECT 'man');
-> END IF;
-> END IF;
-> END $$
Query OK, rows affected (0.14 sec)
mysql> SELECT fn_search(); +---------------+ | fn_search() | +---------------+ | woman | +---------------+ row in set (0.00 sec)
DROP FUNCTION IF EXISTS sp_name
mysql> DROP FUNCTION IF EXISTS customer.sp_search; Query OK, rows affected, warning (0.06 sec)
(1) 列级约束 主要是指对列的类型,取值范围,精度等的约束
(2) 元组约束 指元组中各个字段之间的相互约束,例如某个活动的开始日期小于结束日期
(3) 表级约束 指若干元组之间,关系之间的联系的约束, 例如, 在学生成绩表 tb_score 表中学号 stdentNo 字段的取值受学生信息表 tb_student表中学号 studentNo 字段取值的约束
i) 每个表只能有一个主键
ii) 主键的值不能重复,不能为空
iii) 复合主键不能包含不必要的多余列
iv) 一个列在复合主键的列表中只能出现一次
主键约束可以通过 在 CREATE TABLE 语句中使用关键字 PARIMARY KEY 来实现
i) 作为列的完整性
mysql> CREATE TABLE Myhome(name VARCHAR() PRIMARY KEY,id int()); Query OK, rows affected (0.55 sec)
ii)作为表的完整性, 需要在表中所有列的属性定义后添加PRIMARY KEY(index_col_name,...)格式的子句
候选键的值必须是唯一的,且不能为NULL,可以在CREATE TABLE语句中使用关键字" UNIQUE" 来实现
i) 一个表中只能有一个主键,但可以定义若干候选键
ii) 定义主键约束,系统会自动产生PRIMARY KEY 索引,而定义候选键约束 ,系统会自动产生UNIQUE索引
mysql> ALTER TABLE Myhome ADD UNIQUE KEY 身份证号(id); Query OK, rows affected (0.39 sec)
在MySQL中,参照完整性是通过在 CREATE TABLE 或 更新表 ALTER TABLE 的 同时定义一个外键声明来实现的,有两种方法
i) 在表中某个列的属性定义后直接加上 "reference_definition" 语法项
ii) 在表中所有列的属性定义后添加 "FOREIGN KEY (index_col_name,..) reference_definition" 子句来实现
REFERENCES tbl_name(index_col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option]
reference的语法格式是
RESTRICT | CASCADE | SET NULL | NO ACTION
i) 关键字 " ON DELETE" 或 "ON UPDATE" 指定参照动作相关的SQL语句,这里可为每个外键指定的参照动作分别对应为DELETE语句和UPDATE语句
ii) reference_option语法项 指定参照完整性约束的实现策略,默认为RESTRICT. 具体策略如下: 关键字 "RESTRICT" 表示限制策略,即当要删除或更新被参照表中被更新列上,并在外键中出现的值时,系统拒绝对被参照表的删除或更新操作; 关键字"CASCADE" 表示级联策略,即从被参照表中删除或更新记录时,自动删除或更新表中匹配的记录行; 关键字"SET NULL" 表示置空策略,即当被参照表中删除或更新记录行时,设置参照表中与之对应的外键的值为NULL,这个策略需要被参照表的外键列没有被声明限定词 NOT NULL; NO ACTION表示不采取策略,与RESTRICT语义相同
例 传教订单表order1 要求商品订单order1中所有订购客户信息均已在customer中注册
CREATE TABLE order1
(
order_id INT NOT NULL AUTO_INCREMENT,
order_product CHAR() NOT NULL,
order_product_type CHAR() NOT NULL,
cust_id INT NOT NULL,
order_price DOUBLE NOT NULL,
order_amount INT NOT NULL,
PRIMARY KEY(order_id),
FOREIGN KEY(cust_id)
REFERENCES customer(cust_id)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
当指定一个外键时,需要遵守下列规则:
i)被参照表必须已经用一条CREATE TABLE 语句创建了,或者时当前正在创建的表,若时后一种情形,则被参照表与参照表时同一个表,这样的表叫自照表(self-referencing table),这种结构称为自参照完整性(self_referential integrity)
ii) 必须为被参照表定义主键
iii)必须在被参照表的表名后面知道列名或列组合,这个列或列组合必须时这个被参照表的主键或后候选键
iv)尽管主键不能包含空值,但允许在外键中出现一个空值,这意味着,只要外键的每个非空值出现指定的主键中,这个外键的内容就是正确的
v)文件到列的数目必须和被参照表的主键中的列的数目相同
vi) 外键的列的数据类型必须和被参照表的主键中的对应列的数据类型相同
(1)非空约束 通过在CREATE TABLE 或 ALTER TABLE 语句中的某个列定义后面,加上关键字NOT NULL作为限定字来约束.
(2) CHECK约束 与非空约束一样,CHECK也是通过在CREATE TABLE 或 ALTER TABLE 语句中的某个列定义后面,根据用户的完整性要求来限定约束.
CHECK(pxpr) #貌似MySQL 的CHECK语句无效
命名完整性约束的语法格式是:
CONSTRAINT [symbol] #symbol 是指定的约束名 只能给基于表的完整性约束命名,不能给基于列的完整性约束命名
查看约束
SHOW INDEX IN table_name;
可以用ALTER TABLE语句来更新与列或表有关的各种越苏
i) 完整性约束不能直接修改,若要修改某个实际上是用ALTER TABLE 语句先删除该约束,然后再增加一个与该约束同名的约束
ii) 使用ALTER TABLE 语句, 可以独立地删除完整性约束,而不会删除表本身. 若使用DROP TABLE 语句删除一个表,则表中所有约束讲删除
mysql> ALTER TABLE order1 ADD CONSTRAINT unique1 UNIQUE(order_price); Query OK, rows affected (0.41 sec) Records: Duplicates: Warnings:
CREATE TRIGGER trigger_name trigge_time trigger_event
ON tbl_name FOR EACH ROW trigger_body
i) trigger_name 触发器名称
ii) trigger_time 指定触发的时间,有两个选项,即关键字 BEFORE 和关键字 AFTER ,用于表示触发器是在激活它的语句之前或者之后触发.
iii) trigger_event 指定触发事件, 即指定激活触发器的语句的种类,可以是下述值之一: INSERT, UPDATE, DELETE
iv) tb1_name 指定与触发器相关联的表名.
v) 关键字 " FOR EACH ROW" 指定对于受触发事件影响的每一行都要激活触发器的动作.
vi) rigger_body 指定触发器动作体,如果要执行多个语句,可以使用BEGIN END;
每个表每个事件只允许一个触发器,因此,每个表最多只支持6个触发器; 单一触发器不能与多个事件或多个表关联
例 创建一个触发器,当每次向表 customer 插入一行数据时, 讲用户变量设置为"one customer added!"
mysql> CREATE TRIGGER mysql_test.customer_insert_trigger AFTER INSERT ON mysql_test.customer FOR EACH ROW SET @str = 'one customer added!'; Query OK, rows affected (0.15 sec)
mysql> SELECT @str; +---------------------+ | @str | +---------------------+ | one customer added! | +---------------------+ row in set (0.00 sec)
为了修改一个触发器,必须先删除触发器,然后才能修改
DROP RIGGER [IF EXISTS] [schema_name] trigger_name #schema_name 指定数据库名称
例:
mysql> DROP TRIGGER IF EXISTS mysql_test.customer_insert_trigger; Query OK, rows affected (0.17 sec)
三. 使用触发器
i) 在 INSERT 触发器内,可引用一个名为NEW(不区分大小写) 的虚拟表,来访问被插入的行
ii) 在BEFORE INSERT触发器中, NEW 中的值也可以被更新, 即允许更改被插入的值(只要具有对于的操作权限)
iii) 对于AUTO_INCREMENT 列,NEW 在INSERT 执行之前包含的时0值,在INSERT执行之后将包含新的自动生成值
例 创建一个触发器,当每次向表 customer 插入一行数据时, 讲用户变量设置为 新插入客户的ID号
mysql> CREATE TRIGGER mysql_test.customer_insert_trigger AFTER INSERT ON mysql_test.customer FOR EACH ROW SET @str = NEW.cust_id; Query OK, rows affected (0.16 sec) mysql> INSERT INTO customer VALUES(,'F','武汉','china'); Query OK, row affected (0.23 sec) mysql> SELECT @str; +------+ | @str | +------+ | | +------+ row in set (0.00 sec)
i) 在DELETE 触发器代码内, 可以引用一个名为OLD(不区分大小写) 的虚拟表,来访问被删除的行
ii) OLD中的值全部时只读的,不能被更新
mysql> CREATE TRIGGER mysql_test.customer_delete_trigger AFTER DELETE ON mysql_test.customer FOR EACH ROW SET @str = OLD.cust_id; Query OK, rows affected (0.14 sec)
mysql> DELETE FROM customer WHERE cust_id = ; Query OK, row affected (0.10 sec) mysql> SELECT @str; +------+ | @str | +------+ | | +------+ row in set (0.00 sec)
i)在
i) 在UPDATE触发器代码内, 可以引用一个名为OLD(不区分大小写) 的虚拟表,来访问以前(UPDATE 语句执行前)的值,也可以引用一个名为NEW(不区分大小写)的虚拟表访问新更新的值.
ii) 在BEFORE UPDATE 触发器中, NEW 的值也可能被更新,即允许更改将要用于UPDATE语句中的值
iii) OLD中的字全部是只读的,不能被更新
iv) 当触发器涉及对触发器自身的更新操作时,只能使用BEFORE UPDATE触发器,二AFTER UPDATE触发器将不被允许
mysql> DELIMITER //
mysql> CREATE TRIGGER mysql_test.order1_update_trigger BEFORE UPDATE
-> ON mysql_test.order1 FOR EACH ROW
-> BEGIN
-> IF
-> NEW.order_id <
-> THEN
-> SET NEW.order_product = '哈';
-> END IF;
-> END;//
Query OK, rows affected (0.15 sec)
mysql> UPDATE order1 SET order_product = 'computer' WHERE order_id = ; Query OK, row affected (0.13 sec) Rows matched: Changed: Warnings: mysql> SELECT * FROM order1; +----------+---------------+--------------------+---------+-------------+--------------+ | order_id | order_product | order_product_type | cust_id | order_price | order_amount | +----------+---------------+--------------------+---------+-------------+--------------+ | | 哈 | 电器 | | | | +----------+---------------+--------------------+---------+-------------+--------------+ row in set (0.00 sec)
查看mysql数据库的使用者账户
mysql> SELECT user FROM mysql.user; +------------------+ | user | +------------------+ | root | | mysql.infoschema | | mysql.session | | mysql.sys | | root | +------------------+ r以上就是mysql中的sql的详细内容,更多关于mysql中的sql的资料请关注九品源码其它相关文章!