Usage: mysql [OPTIONS] [database] //命令方式
-?, --help //显示帮助信息并退出
-I, --help //显示帮助信息并退出
--auto-rehash //自动补全功能,就像linux里面,按Tab键出提示差不多,下面有例子
-A, --no-auto-rehash //默认状态是没有自动补全功能的。-A就是不要自动补全功能
-B, --batch //ysql不使用历史文件,禁用交互
(Enables --silent)
--character-sets-dir=name //字体集的安装目录
--default-character-set=name //设置数据库的默认字符集
-C, --compress //在客户端和服务器端传递信息时使用压缩
-#, --debug[=#] //bug调用功能
-D, --database=name //使用哪个数据库
--delimiter=name //mysql默认命令结束符是分号,下面有例子
-e, --execute=name //执行mysql的sql语句
-E, --vertical //垂直打印查询输出
-f, --force //如果有错误跳过去,继续执行下面的
-G, --named-commands
-g, --no-named-commands
-i, --ignore-spaces //忽视函数名后面的空格.
--local-infile //启动/禁用 LOAD DATA LOCAL INFILE.
-b, --no-beep //sql错误时,禁止嘟的一声
-h, --host=name //设置连接的服务器名或者Ip
-H, --html //以html的方式输出
-X, --xml //以xml的方式输出
--line-numbers //显示错误的行号
-L, --skip-line-numbers //忽略错误的行号
-n, --unbuffered //每执行一次sql后,刷新缓存
--column-names //查寻时显示列信息,默认是加上的
-N, --skip-column-names //不显示列信息
-O, --set-variable=name //设置变量用法是--set-variable=var_name=var_value
--sigint-ignore //忽视SIGINT符号(登录退出时Control-C的结果)
-o, --one-database //忽视除了为命令行中命名的默认数据库的语句。可以帮跳过日志中的其它数据库的更新。
--pager[=name] //使用分页器来显示查询输出,这个要在linux可以用more,less等。
--no-pager //不使用分页器来显示查询输出。
-p, --password[=name] //输入密码
-P, --port=# //设置端口
--prompt=name //设置mysql提示符
--protocol=name //使用什么协议
-q, --quick //不缓存查询的结果,顺序打印每一行。如果输出被挂起,服务器会慢下来,mysql不使用历史文件。
-r, --raw //写列的值而不转义转换。通常结合--batch选项使用。
--reconnect //如果与服务器之间的连接断开,自动尝试重新连接。禁止重新连接,使用--disable-reconnect。
-s, --silent //一行一行输出,中间有tab分隔
-S, --socket=name //连接服务器的sockey文件
--ssl //激活ssl连接,不激活--skip-ssl
--ssl-ca=name //CA证书
--ssl-capath=name //CA路径
--ssl-cert=name //X509 证书
--ssl-cipher=name //SSL cipher to use (implies --ssl).
--ssl-key=name //X509 密钥名
--ssl-verify-server-cert //连接时审核服务器的证书
-t, --table //以表格的形势输出
--tee=name //将输出拷贝添加到给定的文件中,禁时用--disable-tee
--no-tee //根--disable-tee功能一样
-u, --user=name //用户名
-U, --safe-updates //Only allow UPDATE and DELETE that uses keys.
-U, --i-am-a-dummy //Synonym for option --safe-updates, -U.
-v, --verbose //输出mysql执行的语句
-V, --version //版本信息
-w, --wait //服务器down后,等待到重起的时间
--connect_timeout=# //连接前要等待的时间
--max_allowed_packet=# //服务器接收/发送包的最大长度
--net_buffer_length=# //TCP / IP和套接字通信缓冲区大小。
--select_limit=# //使用--safe-updates时SELECT语句的自动限制
--max_join_size=# //使用--safe-updates时联接中的行的自动限制
--secure-auth //拒绝用(pre-4.1.1)的方式连接到数据库
--server-arg=name //Send embedded server this as a parameter.
--show-warnings //显示警告
// SQL命令用大写作为普遍的使用规范。
// 创建数据库
CREATE DATABASE 数据库名;
// 判断数据库是否存在并设置字符集编码
CREATE DATABASE 数据库名 [DEFAULT CHARACTER SET '字符编码']; //不能使用 “-”
// 进入一个数据库
USE 数据库名;
// 查看当前数据库
SELECT database();
// 查看数据库
SHOW DATABASES;
SHOW DATABASES LIKE '匹配模式'; // _单个匹配 %多个匹配;可以同时使用
// 查看数据库的创建信息和字符集编码
SHOW CREATE DATABASE 数据库名;
// 更改数据库信息 (一般不用)
ALTER DATABASE 数据库名 CHARSET 字符集;
// 删除数据库
DROP DATABASE 数据库名;
DROP DATABASE [IF EXISTS] 数据库名; // IF EXISTS 判断是否存在 存在删除
// 创建数据表必须同时创建表中的字段
CREATE TABLE 表名(
id TINYINT PRIMARY KEY auto_increment,// PRIMARY KEY 主键 auto_increment自动增长
name VARCHAR(25),
gender boolean,
age INT COMMENT '年龄',
department VARCHAR(20),
salary DOUBLE(7,2)
)ENGINE=INNODB DEFAULT CHARSET=utf8; // ENGINE=INNODB 指定数据库使用的执行引擎,INNODB才支持事务。
CREATE TABLE 数据库名.表名(
数据的字段信息
)DEFAULT CHARSET 'utf8';
/*约束条件:
NOT NULL : 用于控制字段的内容一定不能为空(NULL)。
UNIQUE : 控件字段内容不能重复,一个表允许有多个 Unique 约束。
PRIMARY KEY: 用于控件字段内容不能重复,但它在一个表只允许出现一个。
FOREIGN KEY REFERENCES : 1、约束用于预防破坏表之间连接的动作,FOREIGN KEY 约束。
2. 也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
CHECK: 用于控制字段的值范围。
DEFAULT: 用于设置默认值。
*/
// 查看数据库中的所有表
SHOW TABLES;
// 查看表结构
DESC 表名; // 全称 DESCRIBE 表名;
// 查询mysql表字段信息的sql语句
SHOW DATABASES //列出 MySQL Server 数据库。
SHOW TABLES [FROM db_name] //列出数据库数据表。
SHOW CREATE TABLES tbl_name //数据表结构。
SHOW TABLE STATUS //列出数据表及表状态信息。
SHOW COLUMNS FROM tbl_name [FROM db_name] //列出资料表字段
SHOW FIELDS FROM tbl_name [FROM db_name] // 查看表结构
SHOW FULL COLUMNS FROM tbl_name [FROM db_name] //列出字段及详情
SHOW FULL FIELDS FROM tbl_name [FROM db_name] //列出字段完整属性
SHOW INDEX FROM tbl_name [FROM db_name] //列出表索引。
SHOW STATUS //列出 DB Server 状态。
SHOW VARIABLES //列出 MySQL 系统环境变量。
SHOW PROCESSLIST //列出执行命令。
SHOW GRANTS FOR user //列出某用户权限
// 修改表名
RENAME TABLE 修改的表名 to 新表名
// 添加字段
ALTER TABLE 表名 ADD 字段名 限制条件,ADD 字段名 限制条件;
// 修改一列类型
ALTER TABLE 表名 MODIFY 字段名 类型 [完整性约束条件] [firse | after 字段名];
一: 修改表信息
修改表名
ALTER TABLE test_a RENAME TO sys_app;
修改表注释
ALTER TABLE sys_application COMMENT'系统信息表';
二:修改字段信息
修改字段类型和注释
ALTER TABLE sys_application MODIFY COLUMN app_name varchar(20) COMMENT '应用的名称';
修改字段类型
ALTER TABLE sys_application MODIFY COLUMN app_name TEXT;
设置字段允许为空
ALTER TABLE sys_application MODIFY COLUMN description VARCHAR(255) NULL COMMENT '应用描述';
增加一个字段,设好数据类型,且不为空,添加注释
ALTER TABLE sys_application ADD `url` VARCHAR(255) NOT NULL COMMENT '应用访问地址';
增加主键
ALTER TABLE t_app ADD aid INT(5) NOT NULL , ADD PRIMARY KEY (aid);
增加自增主键
ALTER TABLE t_app ADD aid INT(5) NOT NULL AUTO_INCREMENT , ADD PRIMARY KEY (aid);
修改为自增
ALTER TABLE t_app MODIFY COLUMN aid INT(5) AUTO_INREMENT;
修改字段名字(要重新指定该字段的类型)
ALTER TABLE t_app CHANGE NAME app_name VARCHAR(20) NOT NULL;
删除字段
ALTER TABLE t_app DROP aid;
在某个字段后增加字段
ALTER TABLE t_app ADD COLUMN gateway_id INT NOT NULL DEFAULT 0 AFTER `aid`; #(在 aid 字段后面添加 gateway_id 字段)
调整字段顺序
ALTER TABLE t_app CHANGE gateway_id gateway_id INT NOT NULL AFTER aid ; #(注意gateway_id出现了2次,把gateway_id放在aid之前)
修改字段默认值语法:
ALTER TABLE 表名 ALTER COLUMN 字段名 DROP DEFAULT; (若本身存在默认值,则先删除)
ALTER TABLE 表名 ALTER COLUMN 字段名 SET DEFAULE 默认值;(若本身不存在则可以直接设定)
// 删除一个字段
ALTER TABLE 表名 DROP 字段;
// 删除主键
ALTER TABLE 表名 DROP PRIMARY KEY;
ALTER TABLE table_name DROP PRIMARY KEY;
// 创建多个主键,多个外键关联
CONSTRAINT 外键名称 FOREIGN KEY 创建外键名称 REFERENCES 表名(字段名) ON 约束条件
CREATE TABLE `score` (
`sid` int NOT NULL AUTO_INCREMENT ,
`student_id` int NOT NULL ,
`corse_id` int NOT NULL ,
`number` int NOT NULL ,
PRIMARY KEY (`sid`, `student_id`, `corse_id`),
CONSTRAINT `student_id` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`) ON DELETE NO ACTION,
CONSTRAINT `corse_id` FOREIGN KEY (`corse_id`) REFERENCES `course` (`cid`) ON DELETE NO ACTION
);
-- PS:字段名包裹用的是符号“ ` ”,而不是英文的“ '' ”,其他地方用“ '' 或者 "" ”包裹内容。
1.2.1、数字型
类型 |
大小 |
范围(有符号) |
范围(无符号) |
用途 |
TINYINT |
1 字节 |
(-128,127) |
(0,255) |
小整数值 |
SMALLINT |
2 字节 |
(-32 768,32 767) |
(0,65 535) |
大整数值 |
MEDIUMINT |
3 字节 |
(-8 388 608,8 388 607) |
(0,16 777 215) |
大整数值 |
INT或INTEGER |
4 字节 |
(-2 147 483 648,2 147 483 647) |
(0,4 294 967 295) |
大整数值 |
BIGINT |
8 字节 |
(-9 233 372 036 854 775 808,9 223 372 036 854 775 807) |
(0,18 446 744 073 709 551 615) |
极大整数值 |
FLOAT |
4 字节 |
(-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 字节 |
(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的值 |
小数值/1。2. |
1.2.2、字符串类型
类型 |
范围 |
说明 |
|
Char(N) [ binary] |
N=1~255 个字元 |
固定长度 |
std_name cahr(32) not null |
VarChar(N)[binary] |
N=1~255 个字元 |
可变长度 |
std_address varchar(256) |
TinyBlob |
最大长度255个字元(2^8-1) |
Blob (Binary large objects)储存二进位资料,且有分大小写 Text 文本字符 |
memo text not null |
TinyText |
最大长度255个字元(2^8-1) |
||
Blob |
最大长度65535个字元(2^16-1) |
||
Text |
最大长度65535个字元(2^16-1) |
||
MediumBlob |
最大长度 16777215 个字元(2^24-1) |
||
MediumText |
最大长度 16777215 个字元(2^24-1 |
||
LongBlob |
最大长度4294967295个字元 (2^32-1) |
||
LongText |
最大长度4294967295个字元 (2^32-1) |
||
Enum |
集合最大数目为65535 |
列举(Enumeration),Enum单选、Set复选 |
sex enum(1,0) |
Set |
集合最大数目为64 |
1.2.3、时间日期类型
|
1.3.1、查询语句的执行循序
from -> where -> select -> group by -> having -> order by
1.3.2、查询语句的基本总结
// 从.sql文件引入SQL语句
SOURCE <.SQL文件路径>;
// MySQL可以进行 +,-,*,/ 运算
// 写入内容
INSERT INTO 表名 (字段,字段2,....) VALUES (字段的值,字段值2,....)
INSERT INTO 表名 SET 字段名=字段的值,字段名2=字段的值2;
// 查看表中的内容 \G:将查到的结构纵向显示,后不用加结束符如“;”。
SELECT *(字段) FROM 表名\G;
SELECT 字段,字段2 FROM 表名;
// distinct 过滤重复的内容
SELECT [DISTINCT] * FROM 表名;
SELECT 字段 as 字段别名 FROM 表名;
// 查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
// 子查询 exists(SELECT *(字段) FROM 表名;)
SELECT Student.S#,Student.Sname FROM Student,SC
WHERE Student.S#=SC.S# AND SC.C#='001' AND
EXISTS( SELECT * FROM SC AS SC_2 WHERE SC_2.S#=SC.S# AND SC_2.C#='002');
// WHERE 语句筛选
SELECT * FROM 表名 WHERE 条件;
/* 比较运算符(=、<>、!=、>、>=、!>、<、<=、!<)
between 80 and 100; 值在80到100之间 between...and 和 not between and
in(80,90,100); 值是80或90或100 用来指定列表搜索的条件;
like 'yuan%';
// pattern可以是 % 或 _ ;如果是 % 则表示任意多字符,比如唐%,唐僧,唐国强都符合;
// 如果是 _ 则表示一个字符,唐_ 只有 唐僧 符合,可以加多根 _ ;如唐__ 唐国强符合;
多个条件直接使用逻辑运算符 and:与 or:或 not:非 is:判断
*/
// 排序 Order by 条件 desc 降序(从大到小) asc 升序(从小到大)
SELECT 字段 FROM 表名 WHERE 条件 LIKE 'yuan%' ORDER BY 排序条件 DESC;
// 分组 group by 按分组条件分组后,每一组只显示第一条记录,其他隐藏在组里面。
SELECT * FROM 表名 GROUP BY 按此字段分组;
/* 聚合函数
SUM(字段名) 求指定字段列的和
COUNT(字段名) 返回指定字段列的行数
AVG(字段名) 返回指定字段列的平均值
MIN(字段名) 返回指定字段列的最小值
MAX(字段名) 返回指定字段列的最大值
*/
SELECT name,sum(字段名) FROM 表名 GROUP BY 字段;
// 对分组后进行过滤 having
SELECT name,sum(字段名) FROM 表名 GROUP BY 字段 HAVING sum(字段名)>150;
// limit 获取显示的条数
SELECT * FROM 表名 WHERE 过滤条件 LIMIT 1,5; // 获取到 >=1 <5 的内容
// MySQL 正则
SELECT * FROM 表名 WHERE 过滤条件 REGEXP '正则表达式';
// 修改内容
UPDATE 表名 SET 字段名=字段的值,字段名2=字段的值2 WHERE 条件 ;
UPDATE 表名 SET 字段名=字段的值,字段名2=字段的值2 WHERE id=10 ;
UPDATE 表名 SET 字段名=replace(字段名,'旧内容','新内容') WHERE ID < 200;
// 删除内容
DELETE FROM 表名; // 清空表内容 (逐条删除表中的数据)
DELETE FROM 表名 WHERE 条件; // 删除条件符合的一条内容
WHERE 字段=字段值 AND 字段1=字段值1;
TRUNCATE TABLE 表名;// 删除整张表后再重新创建字段。
// 判断语句的使用
// 查询不为空的数据 is [not] 值
SELECT * FROM 表名 WHERE 字段 IS NOT NULL GROUP BY 按此字段分组;
// top 语句
SELECT TOP 4 * FROM 表名; // 显示前四条信息
1.算术运算符
+ 加 SET var1=2+2; 4
- 减 SET var2=3-2; 1
* 乘 SET var3=3*2; 6
/ 除 SET var4=10/3; 3.3333
DIV 整除 SET var5=10 DIV 3; 3
% 取模 SET var6=10%3 ; 1
2.比较运算符
> 大于 1>2 False
< 小于 2<1 False
<= 小于等于 2<=2 True
>= 大于等于 3>=2 True
BETWEEN 在两值之间 5 BETWEEN 1 AND 10 True
NOT BETWEEN 不在两值之间 5 NOT BETWEEN 1 AND 10 False
IN 在集合中 5 IN (1,2,3,4) False
NOT IN 不在集合中 5 NOT IN (1,2,3,4) True
= 等于 2=3 False
<>, != 不等于 2<>3 False
<=> 严格比较两个NULL值是否相等 NULL<=>NULL True
LIKE 简单模式匹配 "Guy Harrison" LIKE "Guy%" True
REGEXP 正则式匹配 "Guy Harrison" REGEXP "[Gg]reg" False
IS NULL 为空 0 IS NULL False
IS NOT NULL 不为空 0 IS NOT NULL True
3.位运算符
| 或
& 与
<< 左移位
>> 右移位
~ 非(单目运算,按位取反)
4.注释:mysql存储过程可使用两种风格的注释
双横杠:-- 用于单行注释
c风格:/* 注释内容 */ 用于多行注释
5.分支结构
if
case
6.循环结构
for循环
while循环
loop循环
repeat until循环
注:
区块定义,常用
begin
......
end;
也可以给区块起别名,如:
lable:begin
...........
end lable;
可以用leave lable;跳出区块,执行区块以后的代码。
// 外键的使用
// 绑定外键
CREATE TABLE 表名(
// 作为外键一定要与关联的主键数据类型保持一致
FOREIGN KEY (需要绑定外键的字段名) REFERENCES 表名(id(表字段))
)
// 删除关联的内容,需要解除关联关系,或者同时删除相关联的内容。
// 添加外键关联
ALTER TABLE 表名 ADD CONSTRAINT 自定义外键名 FOREIGN KEY (需要绑定外键的字段名) REFERENCES 被绑定表名(id);
// 删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
// 多表查询
SELECT * FROM users u INNER JOIN user_info AS ui WHERE u.info_id = ui.id;
// 外键级联 设置了之后删除主表数据同时也删除了子表记录。
CREATE TABLE 表名(
字段,
FOREIGN KEY (需要绑定外键的字段名) REFERENCES 被绑定表名(id) ON DELETE CASCADE
)
// set NULL 会把子表的记录变成NULL
CREATE TABLE 表名(
字段,
FOREIGN KEY (需要绑定外键的字段名) REFERENCES 被绑定表名(id) ON DELETE SET NULL
)
// 多表查询之联接查询
// 内联接查询 INNER JOIN
// 外联接查询 LEFT JOIN RIGHT JOIN
// 全联接 FULL JOIN (不支持)
// 内联接查询
SELECT * FROM 表名1,表名2 WHERE 表名1.id=表名2.表名1_id;
// 查询与where子句相匹配的信息
SELECT * FROM table1,table2 WHERE table1.id=table2.table1_id;
// 查询与where子句相匹配的字段信息
SELECT table1.id,table1.name,table2.name WHERE table1.id=table2.table1_id;
// 对表名2中匹配表名1中的内容进行查询
// 只显示符合 on 条件信息
SELECT * FROM 表名2 INNER JOIN 表名1 ON 表名1.id=表名2.表名1_id;
// 外联接查询
// 显示 on 后符合条件的信息,而且不符合条件的已NULL显示
SELECT * FROM 表名1 LEFT JOIN 表名2 ON 条件;// 已左表为主查询符合条件的信息,并显示
SELECT * FROM 表名1 RIGHT JOIN 表名2 ON 条件;// 已右表为主查询符合条件的信息
内联接要应用两个逻辑查询处理步骤:它首先像交叉联接一样,对两个输入表进行笛卡尔积运算;然后根据用户指定的谓词对结果行进行过滤。
使用内联接须在两个表之间指定INNER JOIN关键字,当然,INNER关键字是可选的,因为内联接是默认的联接方式,所以可单独指定JOIN关键字。然后利用ON关键字对结果行进行过滤,该谓词也称为联接条件。
下面是一个内联接查询的例子,它对HR数据库中的Employees表和Sales数据库中的Order表执行内联接运算,然后根据谓词条件employees.empid = orders.empid对职员和订单记录进行匹配。
-- INNER JOIN内联接查询
SELECT employees.empid,employees.firstname,employees.lastname,orders.orderid
FROM HR.Employees employees
JOIN Sales.Orders orders ON employees.empid = orders.empid
外联接除了有内联接的两个逻辑处理步骤(即笛卡尔积和ON过滤)之外,还多加一个外联接特有的第三步:添加外部行。
在外联接中,需要将一个表标记为保留表,在两个表之间用LEFT OUTER JOIN连接(OUTER是可选的),LEFT关键字左边表的行是保留的。外联接的第三个逻辑查询处理步骤就是要识别保留表中按照ON条件在另一个表中找不到与之匹配的那些行,然后将这些行添加到联接的前两个步骤生成的结果表中。对于来自联接的非保留表的那些列,追加的外部行中的这些列则用NULL作为占位符。
4.2.1、外联接三表查询示例
使用 LEFT JOIN ... ON ... 语句实现
SELECT
a.body,b.title,c.typename
FROM
dede_addonarticle a
LEFT JOIN
dede_archives b
ON
a.typeid=b.typeid
LEFT JOIN
dede_arctype c
ON
a.typeid=c.id ;
查询结果:
4.2.2、外联接的注意事项
对于外联接查询的总结,需要注意以下几点:
SELECT customers.custid,customers.companyname,orders.orderid
FROM Sales.Customers AS customers
LEFT JOIN HR.Orders AS orders ON customers.custid = orders.custid
WHERE orders.orderid IS NULL -- 使用主键列
-- WHERE orders.custid IS NULL --使用联接列
-- WHERE orders.orderdate IS NULL -- 使用NOT NULL列
-- PS:Sales.Customers 表示 数据库名.表名
数据库索引详细介绍
// 索引查询
CREATE TABLE 表名 (
字段1 数据类型 [完整性约束条件...],
字段2 数据类型 [完整性约束条件...],
// 索引名
[UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY
[索引名] (字段名[(长度)] [ASC | DESC])
);
// INDEX | KEY 普通索引
CREATE TABLE 表名 (
id INT,
name VARCHAR(30),
resume VARCHAR(50),
INDEX index_name (name)
)
// index_name 索引的名称
// 创建唯一索引
CREATE TABLE 表名 (
id INT,
name VARCHAR(30),
UNIQUE INDEX index_name (name)
);
// unique index 表示唯一索引
// 创建全文索引
CREATE TABLE 表名 (
id INT,
name VARCHAR(30),
FULLTEXT INDEX index_name (name)
);
// 创建多列索引
CREATE TABLE 表名 (
id INT,
name VARCHAR(30),
age INT,
INDEX index_name_age (name,age)
);
// 在已存在的字段中添加索引
CREATE [UNIQUT|FULLTEXT|SPATIAL] INDEX 索引名 ON 表名(字段名[(长度)] [ASC|DESC]);
ALTER TABLE 表名 ADD [UNIQUT|FULLTEXT|SPATIAL] INDEX 索引名 ON 表名(字段名[(长度)] [ASC|DESC]);
// 删除索引
DROP INDEX 索引名 ON 表名;
ALTER TABLE 表名 DROP INDEX 索引名;
DROP INDEX index_name ON table_name ;
ALTER TABLE table_name DROP INDEX index_name ;
MySQL函数分为自身的内置函数和自定义函数两种形式,查看 MySQL内置函数的使用 。
自定义函数(user-defined function UDF)就是用一个象ABS() 或 CONCAT()这样的固有(内建)函数一样作用的新函数去扩展MySQL,所以UDF是对MySQL功能的一个扩展,UDF可以没有参数,但UDF必须有且只有一个返回值。
创建UDF:
CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])
RETURNS {STRING|INTEGER|REAL}
runtime_body
/*
CREATE FUNCTION 函数名称(参数列表)
RETURNS 返回值类型
函数体
*/
删除UDF:
DROP FUNCTION function_name
调用自定义函数语法:
SELECT function_name(parameter_value,...)
更对自定义函数的使用方法点击查看:MySQL自定义函数具体使用方法
// 开启事务
start transaction;
Rollback 回滚事务,即撤销指定的sql语句(只能回退insert delete update语句)
Commit 提交事务,提交未存储的事务
savepoint 保留点,事务处理中设置的临时占位符,可以对它发布回退(与整个事务回退不同)
// 保留点的使用
insert delete update 语句后面紧跟 savepoint 语句就为该语句设置了保留点
savepoint 保留点名; //设置保留点
// 回滚到指定的保留点
rollback to 保留点名; // 回滚到指定的保留点位置
-- 数据库锁,保证数据执行正常
bejin; -- 开启事务
select * from 表名 for update; -- 表锁, for update 加锁
select * from 表名 where id=1 for update; -- 行锁
commit; -- 释放事务
引擎名称 |
优点 |
缺陷 |
应用场景 |
MyISAM |
独立于操作系统,这说明可以轻松地将其从Windows服务器移植到Linux服务器,支持表级锁 |
不支持事务/行级锁/外键约束 |
适合管理邮件或Web服务器日志数据 |
InnoDB |
健壮的事务型存储引擎;支持事务/表级锁/行级锁/外键约束自动灾难恢复/AUTO_INCREMENT |
|
需要事务支持,并且有较高的并发读取频率 |
MEMORY |
为得到最快的响应时间,采用的逻辑存储介质是系统内存 |
当mysqld守护进程崩溃时,所有的Memory数据都会丢失;不能使用BLOB和TEXT这样的长度可变的数据类型 |
临时表 |
MERGE |
是MyISAM类型的一种变种。合并表是将几个相同的MyISAM表合并为一个虚表 |
|
常应用于日志和数据仓库 |
ARCHIVE |
归档的意思,支持索引,拥有很好的压缩机制 |
仅支持插入和查询功能 |
经常被用来当做仓库使用 |
1、查看数据库的存储引擎
show engines; //查看mysql所有支持的引擎
//进入数据库,执行这个命令
show variables like '%storage_engine%'; # 查看当前数据库使用的引擎
2、查看当前数据库的字符编码
show variables like '%character_set%';
3、查看数据库的版本号
//进入数据库之后,执行status即可
mysql>status
4、关于varchar
MySQL5.0.3之前varchar(n)这里的n表示字节数;
MySQL5.0.3之后varchar(n)这里的n表示字符数,比如varchar(200),不管是英文还是中文都可以存放200个。
触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。触发器触发条件,在增删改操作的前后进行操作。
--基本语法
CREATE TRIGGER trigger_name trigger_time trigger_event ON table_name FOR EACH ROW
trigger_stmt
其中:
trigger_name:标识触发器名称,用户自行指定;
trigger_time:标识触发时机,取值为 BEFORE 或 AFTER;
trigger_event:标识触发事件,取值为 INSERT、UPDATE 或 DELETE;
table_name:标识建立触发器的表名,即在哪张表上建立触发器;
trigger_stmt:触发器程序体,可以是一句SQL语句,或者用 BEGIN 和 END 包含的多条语句。
由此可见,可以建立6种触发器,即:BEFORE INSERT、BEFORE UPDATE、BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE。
另外有一个限制是不能同时在一个表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。
MySQL 除了对 INSERT、UPDATE、DELETE 基本操作进行定义外,还定义了 LOAD DATA 和 REPLACE 语句,这两种语句也能引起上述6中类型的触发器的触发。
LOAD DATA 语句用于将一个文件装入到一个数据表中,相当与一系列的 INSERT 操作。
REPLACE 语句一般来说和 INSERT 语句很像,只是在表中有 primary key 或 unique 索引时,如果插入的数据和原来primary key 或 unique 索引一致时,会先删除原来的数据,然后增加一条新数据,也就是说,一条 REPLACE 语句有时候等价于一条 INSERT 语句,有时也等价于一条 DELETE 语句加上一条 INSERT 语句。
INSERT 型触发器:插入某一行时激活触发器,可能通过 INSERT、LOAD DATA、REPLACE 语句触发;
UPDATE 型触发器:更改某一行时激活触发器,可能通过 UPDATE 语句触发;
DELETE 型触发器:删除某一行时激活触发器,可能通过 DELETE、REPLACE 语句触发。
DELIMITER $
-- 为takes表创建名为credit_get的update触发器,在更新之后(after)执行
create trigger credit_get after update on takes for each row
begin
-- if条件判断成立执行then后的语句
if (NEW.grade <> 'F' and NEW.grade is not null) and (OLD.grade = 'F' or OLD.grade is null))
then
update student set tot_cred = tot_cred + (select credits from course where course.course_id = NEW.course_id) where student.ID = NEW.ID;
end if;
end $
DELIMITER ;
注意事项:
after触发器-->是在记录操纵之后触发,是先完成数据的增删改,再触发,触发的语句晚于监视的增删改操作,无法影响前面的增删改动作;
before触发器-->是在记录操纵之前触发,是先完成触发,再增删改,触发的语句先于监视的增删改,我们就有机会判断,修改即将发生的操作;如:我们在触发之前需要判断new值和old值的大小或关系,如果满足要求就触发,不通过就修改再触发;如:表之间定义的有外键,在删除主键时,必须要先删除外键表,这时就有先后之分,这里before相当于设置了断点,我们可以处理删除外键。
对于INSERT语句, 只有NEW是合法的;
对于DELETE语句,只有OLD才合法;
对于UPDATE语句,NEW、OLD可以同时使用。
在MySQL中,BEGIN … END 语句的语法为:
BEGIN
[statement_list]
END
其中,statement_list 代表一个或多个语句的列表,列表内的每条语句都必须用分号(;)来结尾。而在MySQL中,分号是语句结束的标识符,遇到分号表示该段语句已经结束,MySQL可以开始执行了。因此,解释器遇到statement_list 中的分号后就开始执行,然后会报出错误,因为没有找到和 BEGIN 匹配的 END。
这时就会用到 DELIMITER 命令(DELIMITER 是定界符,分隔符的意思),它是一条命令,不需要语句结束标识,语法为:
DELIMITER new_delemiter
new_delemiter 可以设为1个或多个长度的符号,默认的是分号(;),我们可以把它修改为其他符号,如$:
DELIMITER $ 在这之后的语句,以分号结束,解释器不会有什么反应,只有遇到了$,才认为是语句结束。注意,使用完之后,我们还应该记得把它给修改回来。
例子:
假设系统中有两个表:
班级表 class(班级号 classID, 班内学生数 stuCount)
学生表 student(学号 stuID, 所属班级号 classID)
要创建触发器来使班级表中的班内学生数随着学生的添加自动更新,代码如下:
DELIMITER $ --定义语句终止符为“$”
--为student表创建名为tri_stuInsert的insert触发器,在创建之前(before)执行
create trigger tri_stuInsert before insert on student for each row
begin --开始
declare c int; -- 定义 c 为 int 类型
set c = (select stuCount from class where classID=new.classID); -- set 变量名=设置值;
update class set stuCount = c + 1 where classID = new.classID;
end$ --end表示结束,“$” 表示语句结束。
DELIMITER ;
MySQL 中使用 DECLARE 来定义一局部变量,该变量只能在 BEGIN … END 复合语句中使用,并且应该定义在复合语句的开头,即其它语句之前,语法如下:
DECLARE var_name[,...] type [DEFAULT value]
其中:
var_name 为变量名称,同 SQL 语句一样,变量名不区分大小写;type 为 MySQL 支持的任何数据类型;可以同时定义多个同类型的变量,用逗号隔开;变量初始值为 NULL,如果需要,可以使用 DEFAULT 子句提供默认值,值可以被指定为一个表达式。
对变量赋值采用 SET 语句,语法为:
SET var_name = expr [,var_name = expr] ...
上述示例中使用了NEW关键字,和 MS SQL Server 中的 INSERTED 和 DELETED 类似,MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。
具体地:
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名),另外,OLD 是只读的,而 NEW 则可以在触发器中使用 SET 赋值,这样不会再次触发触发器,造成循环调用(如每插入一个学生前,都在其学号前加“2013”)。
和查看数据库(show databases;)查看表格(show tables;)一样,查看触发器的语法如下:
SHOW TRIGGERS [FROM schema_name];
其中,schema_name 即 Schema 的名称,在 MySQL 中 Schema 和 Database 是一样的,也就是说,可以指定数据库名,这样就不必先“USE database_name;”了。
和删除数据库、删除表格一样,删除触发器的语法如下:
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL 会回滚事务,有:
a、MySQL的触发器是按照BEFORE触发器、行操作、AFTER触发器的顺序执行的,其中任何一步发生错误都不会继续执行剩下的操作。
b、如果 BEFORE 触发器执行失败,SQL 无法正确执行。
c、SQL 执行失败时,AFTER 型触发器不会触发。
d、AFTER 类型的触发器执行失败,SQL 会回滚。
触发器会有以下两种限制:
1、触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL语句,但是允许存储程序通过参数将数据返回触发程序,也就是存储过程或者函数通过OUT或者INOUT类型的参数将数据返回触发器是可以的,但是不能调用直接返回数据的过程。
2、不能再触发器中使用以显示或隐式方式开始或结束事务的语句,如START TRANS-ACTION,COMMIT或ROLLBACK。
// 视图:视图被称为虚拟表,存放在数据库中,并且视图只能进行查询。
// 创建视图
CREATE VIEW 视图名 AS sql语句;
// 修改视图
CREATE OR REPLACE VIEW 视图名 AS select语句;
// 使用
SELECT * FROM 视图名;
// 删除视图
DROP VIEW 视图名;
视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据库中的。通过视图,可以展现基表的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。使用视图的大部分情况是为了保障数据安全性,提高查询效率。
基表:用来创建视图的表叫做基表base table。
视图优点:
1)简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。
2)安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。
3)数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
1)OR REPLACE:表示替换已有视图
2)ALGORITHM:表示视图选择算法,默认算法是UNDEFINED(未定义的):MySQL自动选择要使用的算法 ;merge合并;temptable临时表
3)select_statement:表示select语句
4)[WITH [CASCADED | LOCAL] CHECK OPTION]:表示视图在更新时保证在视图的权限范围之内
cascade是默认值,表示更新视图的时候,要满足视图和表的相关条件
local表示更新视图的时候,要满足该视图定义的一个条件即可
TIPS:推荐使用WHIT [CASCADED|LOCAL] CHECK OPTION选项,可以保证数据的安全性
基本格式:
create view <视图名称>[(column_list)]
as select语句
with check option;
1、在单表上创建视图
mysql> create view v_F_players(编号,名字,性别,电话)
-> as
-> select PLAYERNO,NAME,SEX,PHONENO from PLAYERS
-> where SEX='F'
-> with check option;
Query OK, 0 rows affected (0.00 sec)
mysql> desc v_F_players;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| 编号 | int(11) | NO | | NULL | |
| 名字 | char(15) | NO | | NULL | |
| 性别 | char(1) | NO | | NULL | |
| 电话 | char(13) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> select * from v_F_players;
+--------+-----------+--------+------------+
| 编号 | 名字 | 性别 | 电话 |
+--------+-----------+--------+------------+
| 8 | Newcastle | F | 070-458458 |
| 27 | Collins | F | 079-234857 |
| 28 | Collins | F | 010-659599 |
| 104 | Moorman | F | 079-987571 |
| 112 | Bailey | F | 010-548745 |
+--------+-----------+--------+------------+
5 rows in set (0.02 sec)
2、在多表上创建视图
mysql> create view v_match
-> as
-> select a.PLAYERNO,a.NAME,MATCHNO,WON,LOST,c.TEAMNO,c.DIVISION
-> from
-> PLAYERS a,MATCHES b,TEAMS c
-> where a.PLAYERNO=b.PLAYERNO and b.TEAMNO=c.TEAMNO;
Query OK, 0 rows affected (0.03 sec)
mysql> select * from v_match;
+----------+-----------+---------+-----+------+--------+----------+
| PLAYERNO | NAME | MATCHNO | WON | LOST | TEAMNO | DIVISION |
+----------+-----------+---------+-----+------+--------+----------+
| 6 | Parmenter | 1 | 3 | 1 | 1 | first |
| 44 | Baker | 4 | 3 | 2 | 1 | first |
| 83 | Hope | 5 | 0 | 3 | 1 | first |
| 112 | Bailey | 12 | 1 | 3 | 2 | second |
| 8 | Newcastle | 13 | 0 | 3 | 2 | second |
+----------+-----------+---------+-----+------+--------+----------+
5 rows in set (0.04 sec)
视图将我们不需要的数据过滤掉,将相关的列名用我们自定义的列名替换。视图作为一个访问接口,不管基表的表结构和表名有多复杂。
如果创建视图时不明确指定视图的列名,那么列名就和定义视图的select子句中的列名完全相同;
如果显式的指定视图的列名就按照指定的列名。
注意:显示指定视图列名,要求视图名后面的列的数量必须匹配select子句中的列的数量。
1、使用show create view语句查看视图信息
mysql> show create view v_F_players\G;
*************************** 1. row ***************************
View: v_F_players
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_F_players` AS select `PLAYERS`.`PLAYERNO` AS `编号`,`PLAYERS`.`NAME` AS `名字`,`PLAYERS`.`SEX` AS `性别`,`PLAYERS`.`PHONENO` AS `电话` from `PLAYERS` where (`PLAYERS`.`SEX` = 'F') WITH CASCADED CHECK OPTION
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
2、视图一旦创建完毕,就可以像一个普通表那样使用,视图主要用来查询
mysql> select * from view_name;
3、有关视图的信息记录在information_schema数据库中的views表中
mysql> select * from information_schema.views
-> where TABLE_NAME='v_F_players'\G;
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: TENNIS
TABLE_NAME: v_F_players
VIEW_DEFINITION: select `TENNIS`.`PLAYERS`.`PLAYERNO` AS `编号`,`TENNIS`.`PLAYERS`.`NAME` AS `名字`,`TENNIS`.`PLAYERS`.`SEX` AS `性别`,`TENNIS`.`PLAYERS`.`PHONENO` AS `电话` from `TENNIS`.`PLAYERS` where (`TENNIS`.`PLAYERS`.`SEX` = 'F')
CHECK_OPTION: CASCADED
IS_UPDATABLE: YES
DEFINER: root@localhost
SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
1 row in set (0.00 sec)
1、CREATE OR REPLACE VIEW语句修改视图
基本格式:
create or replace view view_name as select语句;
在视图存在的情况下可对视图进行修改,视图不在的情况下可创建视图
2、ALTER语句修改视图
ALTER
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
注意:修改视图是指修改数据库中已存在的表的定义,当基表的某些字段发生改变时,可以通过修改视图来保持视图和基本表之间一致
3、DML操作更新视图
因为视图本身没有数据,因此对视图进行的dml操作最终都体现在基表中
mysql> create view v_student as select * from student;
mysql> select * from v_student;
+--------+--------+------+
| 学号 | name | sex |
+--------+--------+------+
| 1 | 张三 | M |
| 2 | 李四 | F |
| 5 | 王五 | NULL |
+--------+--------+------+
mysql> update v_student set name='钱六' where 学号='1';
mysql> select * from student;
+--------+--------+------+
| 学号 | name | sex |
+--------+--------+------+
| 1 | 钱六 | M |
| 2 | 李四 | F |
| 5 | 王五 | NULL |
+--------+--------+------+
当然,视图的DML操作,不是所有的视图都可以做DML操作。
有下列内容之一,视图不能做DML操作:
①select子句中包含distinct
②select子句中包含组函数
③select语句中包含group by子句
④select语句中包含order by子句
⑤select语句中包含union 、union all等集合运算符
⑥where子句中包含相关子查询
⑦from子句中包含多个表
⑧如果视图中有计算列,则不能更新
⑨如果基表中有某个具有非空约束的列未出现在视图定义中,则不能做insert操作
4、drop删除视图
删除视图是指删除数据库中已存在的视图,删除视图时,只能删除视图的定义,不会删除数据,也就是说不动基表:
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
mysql> drop view v_student;
如果视图不存在,则抛出异常;使用IF EXISTS选项使得删除不存在的视图时不抛出异常。
对于可以执行DML操作的视图,定义时可以带上WITH CHECK OPTION约束
作用:
对视图所做的DML操作的结果,不能违反视图的WHERE条件的限制。
示例:创建视图,包含1960年之前出生的所有球员(老兵)
mysql> create view v_veterans
-> as
-> select * from PLAYERS
-> where birth_date < '1960-01-01'
-> with check option;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from v_veterans;
+----------+---------+----------+------------+-----+--------+----------------+---------+----------+-----------+------------+----------+
| PLAYERNO | NAME | INITIALS | BIRTH_DATE | SEX | JOINED | STREET | HOUSENO | POSTCODE | TOWN | PHONENO | LEAGUENO |
+----------+---------+----------+------------+-----+--------+----------------+---------+----------+-----------+------------+----------+
| 2 | Everett | R | 1948-09-01 | M | 1975 | Stoney Road | 43 | 3575NH | Stratford | 070-237893 | 2411 |
| 39 | Bishop | D | 1956-10-29 | M | 1980 | Eaton Square | 78 | 9629CD | Stratford | 070-393435 | NULL |
| 83 | Hope | PK | 1956-11-11 | M | 1982 | Magdalene Road | 16A | 1812UP | Stratford | 070-353548 | 1608 |
+----------+---------+----------+------------+-----+--------+----------------+---------+----------+-----------+------------+----------+
3 rows in set (0.02 sec)
此时,使用update对视图进行修改:
mysql> update v_veterans
-> set BIRTH_DATE='1970-09-01'
-> where PLAYERNO=39;
ERROR 1369 (HY000): CHECK OPTION failed 'TENNIS.v_veterans'
因为违反了视图中的WHERE birth_date < '1960-01-01'子句,所以抛出异常;
利用with check option约束限制,保证更新视图是在该视图的权限范围之内。
嵌套视图:定义在另一个视图的上面的视图
mysql> create view v_ear_veterans
-> as
-> select * from v_veterans
-> where JOINED < 1980;
使用WITH CHECK OPTION约束时,(不指定选项则默认是CASCADED)
可以使用CASCADED或者 LOCAL选项指定检查的程度:
①WITH CASCADED CHECK OPTION:检查所有的视图
例如:嵌套视图及其底层的视图
②WITH LOCAL CHECK OPTION:只检查将要更新的视图本身
对嵌套视图不检查其底层的视图
CREATE [OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
1、ALGORITHM选项:选择在处理定义视图的select语句中使用的方法
①UNDEFINED:MySQL将自动选择所要使用的算法
②MERGE:将视图的语句与视图定义合并起来,使得视图定义的某一部分取代语句的对应部分
③TEMPTABLE:将视图的结果存入临时表,然后使用临时表执行语句
缺省ALGORITHM选项等同于ALGORITHM = UNDEFINED
2、DEFINER选项:指出谁是视图的创建者或定义者
①definer= '用户名'@'登录主机'
②如果不指定该选项,则创建视图的用户就是定义者,指定关键字CURRENT_USER(当前用户)和不指定该选项效果相同
3、SQL SECURITY选项:要查询一个视图,首先必须要具有对视图的select权限。
但是,如果同一个用户对于视图所访问的表没有select权限,那会怎么样?
SQL SECURITY选项决定执行的结果:
①SQL SECURITY DEFINER:定义(创建)视图的用户必须对视图所访问的表具有select权限,也就是说将来其他用户访问表的时候以定义者的身份,此时其他用户并没有访问权限。
②SQL SECURITY INVOKER:访问视图的用户必须对视图所访问的表具有select权限。
缺省SQL SECURITY选项等同于SQL SECURITY DEFINER
视图权限总结:
使用root用户定义一个视图(推荐使用第一种):u1、u2
1)u1作为定义者定义一个视图,u1对基表有select权限,u2对视图有访问权限:u2是以定义者的身份访问可以查询到基表的内容;
2)u1作为定义者定义一个视图,u1对基表没有select权限,u2对视图有访问权限,u2对基表有select权限:u2访问视图的时候是以调用者的身份,此时调用者是u2,可以查询到基表的内容。
示例:所有有罚款的球员的信息
创建视图:
mysql> create view cost_raisers
-> as
-> select * from PLAYERS
-> where playerno in (select playerno from PENALTIES);
查询视图:
mysql> select playerno from cost_raisers
-> where town='Stratford';
+----------+
| PLAYERNO |
+----------+
| 6 |
+----------+
1、替代方法:
先把select语句中的视图名使用定义视图的select语句来替代;
再处理所得到的select语句。
mysql> select playerno from
-> (
-> select * from PLAYERS
-> where playerno in -> (select playerno from PENALTIES)
-> ) as viewformula
-> where town='Stratford';
+----------+
| PLAYERNO |
+----------+
| 6 |
+----------+
2、具体化方法:
先处理定义视图的select语句,这会生成一个中间的结果集;
然后,再在中间结果上执行select查询。
mysql> select <列名> from <中间结果>;
存储过程如同一门程序设计语言,同样包含了数据类型、流程控制、输入和输出和它自己的函数库。
-- 修改SQL语句的结束符
delimiter $$ --将 “;” 修改为了 “$$”
例:SHOW TABLES$$
-- 存储过程使用
CREATE PROCEDURE 存储过程名()
BEGIN -- 存储过程代码开始
declare i int default 1;-- 定义变量 i 默认值为 1
while (1<50000) do
INSERT INTO 数据库名.表名 VALUES (i,'yuan');
set i=i+1; -- 设置变量
end while; --结束while循环
END$$ -- 存储过程代码结束
基本语法:call sp_name()
注意:存储过程名称后面必须加括号,哪怕该存储过程没有参数传递
1.基本语法:
drop procedure sp_name;
2.注意事项:不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
1.show procedure status;
显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等。
2.show create procedure sp_name;
显示某一个MySQL存储过程的详细信息。
IN 输入参数
表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值。
OUT 输出参数
该值可在存储过程内部被改变,并可返回。
INOUT 输入输出参数
调用时指定,并且可被改变和返回。
IN参数例子:
CREATE PROCEDURE sp_demo_in_parameter(IN p_in INT)
BEGIN
SELECT p_in; --查询输入参数
SET p_in=2; --修改
SELECT p_in;--查看修改后的值
END;
执行结果:
SET @p_in=1
CALL sp_demo_in_parameter(@p_in)
SELECT @p_in;
以上可以看出,p_in虽然在存储过程中被修改,但并不影响@p_id的值
OUT参数例子:
CREATE PROCEDURE sp_demo_out_parameter(OUT p_out INT)
BEGIN
SELECT p_out;/*查看输出参数*/
SET p_out=2;/*修改参数值*/
SELECT p_out;/*看看有否变化*/
END;
执行结果:
SET @p_out=1
CALL sp_demo_out_parameter(@p_out)
SELECT @p_out;
INOUT参数例子:
CREATE PROCEDURE sp_demo_inout_parameter(INOUT p_inout INT)
BEGIN
SELECT p_inout;
SET p_inout=2;
SELECT p_inout;
END;
执行结果:
SET @p_inout=1
CALL sp_demo_inout_parameter(@p_inout)
SELECT @p_inout;