MySQL入门

####1.初始MySQL####
 ##1.1使用DDL语句操作数据库
在DOS中运行数据库使用命令:mysql -h 服务器主机地址 -u 用户名 -p密码
1.1.1创建数据库
CREATE DATABASE 数据库名;
1.1.2查看数据库列表
SHOW DATABASES;
1.2.3选择数据库
USE 数据库名;
1.2.4删除数据库
DROP DATABASE 数据库名;
 ##1.2使用DDL语句操作数据表
1.2.1数据类型
1.数值类型
数据类型 字节数
TINYINT[(M)] 1字节
SMALLINT[(M)] 2字节
MEDIUMINT[(M)] 3字节
INT[(M)] 4字节
BIGIINT[(M)] 8字节
FLOAT[(M,D)] 4字节
DOUBLE[(M,D)] 8字节
DECIMAL [(M[,D])] M+2字节     M:最大精度位数即总位数,M的取值范围是1~65,默认值是10,D:小数位精度位数,D的取值范围是0~30
2.字符串类型
数据类型 字节数 说明
CHAR[(M)] M字节 固定字节
VARCHAR[(M)] 可变长度 可变字节
TINYTEXT 0~255 微型文本串
TEXT 0~65535 文本串
3.日期类型
数据类型 格式
DATE YYYY-MM-DD
DATETIME YY-MM-DD hh:mm:ss:
TIME hh:mm:ss:
TIMESTAMP YYYYMMDDHHMMSS 当你插入null时候默认是当前时间
YEAR YYYY格式的年份
1.2.2创建表
1.语法
CREATE TABLE [IF NOT EXISTS] 表名(
字段1 数据类型[字段属性|约束][索引][注释],
字段2 数据类型[字段属性|约束][索引][注释],
)[表类型][表字符集][注释];
1.2.3常用的属性约束
字段属性、约束名 关键字
非空约束 NOT NULL
默认约束 DEFAULT
唯一约束 UNIQUE KEY(UK)
主键约束 PRIMARY KEY(PK)
外键约束 FOREIGN KEY(FK)
自动增长 AUTO_INCREMENT
零填充 ZEROFILL
非负数 UNSIGNED
注释 COMMENT
1.单字段主键
例如:CREATE TABLE student(
`studentNo` INT(4) PRIMARY KEY,
....
);
或CREATE TABLE student(
`studentNo` INT(4),
....
PRIMARY KEY(`id`)
);
2.多字段主键
CREATE TABLE student(
`studentNo` INT(4),
.... PRIMARY KEY
PRIMARY KEY(`id`,`name`)
);
3.注释
CREATE TABLE student(
`studentNo` INT(4) UNSIGNED COMMENT `编号`,
....
)COMMENT=`测试表`;
4.编码格式设置
CREATE TABLE [IF NOT EXISTS] 表名(
#省略代码
)CHARSET=`字符集名`;
1.2.4查看表
SHOW DATABASES;
USE 数据库名;
SHOW TABLES;
SHOW VARIABLES;#展示所有变量
SHOW VARIABLES LIKE "%char%";#展示所有变量包含char这个字符的所有变量
查看表的定义,DESCRIBE 表名;或者DESC 表名;
1.2.5在DOS窗口显示MYSQL数据库内容时,中文可能出现乱码,这是因为DOS窗口默认字符集为GBK格式,如果当前MySQL设置的默认编码格式非GBK格式,在输出信息之前,执行以下语句;
SET NAMES gbk;
1.2.5删除表
DROP TABLE 表名;
1.2.6插入数据
#插入单个数据,其他计算机默认处理
INSERT INTO dog (birthday) VALUES("1997-1-1");
 ##1.3修改表##
1.3.1修改表名
ALTER TABLE (旧表名) RENAME (新表名);
1.3.2添加字段
ALTER TABLE 表名 ADD 字段名 数据类型 [属性];
1.3.3修改字段
ALTER TABLE 表名 CHANGE 原字段名 现字段名 数据类型 [属性];
1.3.4删除字段
ALTER TABLE 表名 DROP 字段名;
1.3.5添加主键约束
ALTER TABLE 表名 ADD CONSTRAINT 主键名 PRIMARY KEY 表名 (主键字段);
1.3.6添加外键约束
//ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY(外键字段) REFERENCES 关联表名 (关联字段);
ALTER TABLE 表名 ADD FOREIGN KEY(外键字段) REFERENCES 关联表名 (关联字段);
 ##1.4mysql系统帮助
1.4.1查看帮助文档目录列表
HELP contents命令查看帮助文档目录列表,
1.4.2查看具体内容
HELP data Types;命令可以选择某一项进行查询,
若进一步查看某一数据类型,如int类型,命令如下:HELP INT;
还可以查询某命令,如:HELP CREATE TABLE;
   ####2.DML和DDL####
 ##2.1使用DML插入数据##
2.1.1使用insert插入数据
insert into 表名 [{字段名列表}] values (值列表);
 1.插入多行数据
intsert into 表名 values (值列表1),(值列表2),....(值列表n)
 2.将查询结果插入到新表
create table 新表(select 字段 from 原表);
 ##2.2使用DML更新数据##
2.2.1语法
update 表名 set 字段=更新值 [where 更新条件]
 ##2.3使用DML删除数据
delete from 表名 where 条件;
注意:
truncate会重置auto_increment,不能按照条件删除,速度快
delete不会重置auto_increment,能按照条件删除
语法:
truncate table 表名
条件中:
and 逻辑与 or逻辑或 not 逻辑非
like 像   %任意个字符 _任意一个字符
 ##2.4DQL语句## 
   2.4.1使用select语句
语法:
select <列名|表达式|函数|常量>//给列名取别名AS,合并列名使用CONCAT(列名1+列名2)
from <表名>
[where <查询条件表达式>]
[order by <排序的列名>[ASC或DESC]];
例:ORDER BY 读者编号 DESC,借书日期 ASC
select CAST(rid AS signed) from borrow ORDER BY 1;
去重distinct:SELECT DISTINCT * FROM result;
提取limit:SELECT DISTINCT * from result where SubjectNo=8 ORDER BY StudentResult ASC LIMIT 0,3;0代表起始位置,3代表条数
分组group by:SELECT gradeid,COUNT(*) from student GROUP BY GradeID;group by 在where语句后面
筛选having:SELECT gradeid,COUNT(*) from student GROUP BY GradeID HAVING count(gradeid)>20;分组之后再筛选
连接UNION:select * from penalty UNION select "aaa","a","bb","bb";UNION ALL 不去重
   1.查询中使用列的别名
AS
2.查询空值
where 字段 is null//is not null;
3.查询中使用常量列
select * "aaa" as bb from student;
2.4.2常用函数
1.聚合函数
AVG() 返回某个字段的平均值
COUNT() 返回某字段的行数
MAX() 返回某个字段的最大值
MIN() 返回某个字段的最小值
2.字符串函数
CONCAT(STR1,STR2...) 连接字符串str1,str2为完整的一个字符串
INSERT(str,pos,len,newstr) 将字符串str从pos位置开始,len个字符长的子串替换为字符串newstr
LOWER(str) 将字符串str中所有的字符串变为小写
URRER(str) 将字符串str中所有的字符串变为大写
SUBSTRING(str,num,len) 返回字符串str的第num个位置开始长度为len的字符串
3.时间日期函数
CURDATE() 获取当前日期
CURTIME() 获取当前时间
NOW() 获取当前日期与时间
WEEK(date) 返回日期date为一年中的第几周
YEAR(date) 返回日期date的年份
HOUR(time) 返回时间的小时值
MINUTE(time) 返回时间time的分钟值
DATEDIFF(date1,date2) 返回日期参数date1和date2之间相隔的天数
ADDDATE(date,n) 计算日期参数date加上n天后的日期
   4.数学函数
CEIL(X) 返回大于或等于数值X的最小整数
FLOOR(X) 返回小于或等于数值x的最大整数
RAND() 返回0~1间的随机数
 ##2.5order by语句
2.5.1如果需要一定的顺序排序查询语句中的行,则需要使用order by语句,并且排序可以是升序(ASC),可以是降序(DESC)
limit[位置偏移量,[行数]];
位置偏移量指从结果集中第几条数据开始显示,从0开始表示第1条数据
行数指显示记录的条数
 ##2.6子查询##
2.6.1简单子查询
当条件约束的字段不在本表上,使用子查询
   2.6.2in和not in子查询
使用比较运算符时,子查询只能返回一条或空的记录,而只要把运算符改成in就可以返回不唯一的值
查询学号是203和207和205的学生信息:select * from student where studentNo in (203,205,207);
 ##2.7连接查询##
例:SELECT * from student,grade
WHERE student.GradeId=grade.GradeID;//内连接
或者:SELECT * from student s INNER JOIN grade as g
on s.GradeId=g.GradeID;//内连接
左外连接:SELECT * from student s left JOIN grade as g
on s.GradeId=g.GradeID;
强行留下左边表匹配剩下的数据
右外链接:SELECT * from student s right JOIN grade as g
on s.GradeId=g.GradeID;
强行留下右边表匹配剩下的数据
####3.高级查询####
 ##3.1EXISTS和NOT EXISTS子查询
3.1.1EXTISTS子查询
语法:select ... from 表名 where EXISTS(子查询);
EXISTS 关键字后面的参数是一个任意的子查询,如果子查询有返回行,则EXISTS子查询的结果为true,此时再执行外层查询语句。如果没有则不执行
3.1.2NOT EXTISTS子查询
语法:select ...from 表名 where  not exists(子查询)
 ##3.2子查询注意事项
嵌套在select语句的select子句中的子查询语句如下:
select (子查询) from 表名;
嵌套在select语句的from子句中的子查询语句如下:
select * from (子查询) as 表的别名;
注意 执行上面的语句时as不能漏
还可以 group by,having子句中包含子查询
 ##3.3分组查询
3.3.1使用group by进行分组查询
  执行方法在where条件后面
3.3.2使用HAVING子句进行分组筛选
对分组后的条件筛选必须使用HAVING子句
 ##3.4多表连接查询
3.4.1内连接查询
1.在where子句中指定连接条件
SELECT student.studentNamen,result.subjectNo,result.studentResult 
from student,result
WHERE student.GradeId=result.GradeID;
2.在FROM子句中使用inner join...on来实现
SELECT * from student s 
INNER JOIN grade as g
on s.GradeId=g.GradeID;
3.4.2外连接查询
1.左外连接查询
SELECT * from student s left JOIN grade as g
on s.GradeId=g.GradeID;
以学生信息表作为主表(也叫左表),强行留下左边表匹配剩下的数据,右边的grade表如果没有找到相匹配的记录,则返回NULL值来填充数据
2.右外连接查询
SELECT * from student s right JOIN grade as g
on s.GradeId=g.GradeID;
 和上面相反
3.4.3创建临时表(虚表)
create temporary table 表名(查询语句)
QUARTER(hos_house.htime) 获取季度
####4.事务、视图、索引、备份和恢复####
 ##4.1事务
语法:
begin;-- 开始事务或者start transaction;
set autocommit=0|1;-- 设置关闭或打开自动提交
rollback; -- 回滚
commit;  -- 真正的提交数据

-- 正常处理事务的逻辑
-- 1.开启事务
BEGIN; -- 开启事务之后,所有操作都不会提交
UPDATE account set money=money-500 WHERE NAME='zy';
ROLLBACK; -- 回滚
COMMIT; -- 提交事务
事务的特性:
原子性:事务是一个完整的操作,事务的各步操作是不可分的,要么都执行,要么都不执行
一致性:当事务完成时,数据必须处于一致状态
隔离性:并发事务之间彼此隔离,独立,它不应以任何方式依赖于或影响其他事务
持久性:事务完成后,它对数据库的修改被永久保持
 ##4.2视图
语法:create view 视图名 as (select 语句)
对视图数据增删改直接影响所引用表中的数据
降低sql查询语句编写难度
 ##4.3索引
语法:create index 索引名字 On 表名(字段)
索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点。
考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录。
如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,
如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),
则总共需要100s(但实际上要好很多很多)。如果对之建立B-Tree索引,则只需要进行log100(10^6)=3次页面读取,最坏情况下耗时30ms。
这就是索引带来的效果,很多时候,当你的应用程序进行SQL查询速度很慢时,应该想想是否可以建索引。
查询索引:show index from 表名\G;//查询语句后面加\G,表示结果集按列表示
删除索引:drop index 索引名 on 表名 
 ##4.4备份和恢复
4.4.1使用mysqldump命令备份数据库
语法:mysqldump -u username -h host -p password dbname[tbname1,[tbname2....]]>filename.sql
在dos中直接输入命令可完成备份
例:mysqldump -uroot -p 11 account>F:\java视频\account.sql
4.4.2使用mysqldump命令恢复数据库
语法:mysql -u username -p [dbname]<filename.sql
在未创建数据库执行语句会报错,使用create创建数据库名之后,恢复数据库成功,
   执行quit语句退出mysql环境
    如果已经登录了数据库服务器,也可以使用source命令恢复数据库
source filename;
例:source d:\backup\myschool.sql;
4.4.3表数据导出到文本文件
select * from 表名
where 条件
into outfile:'filename'
为使得导出的文本文件可读性更好,可在select...into outfile在语句后设置相应的参数选项
如下
fields terminated by ‘string’ :用来设置字段的分隔符为字符串对象,默认为'\t'
fields[optionally]  enclosed by 'char'  : 用来设置阔上字段值的字符符号,如果使用了optionally,则只有char和varchar等字符数据字段被包括,默认情况下不适用任何字符
fields escaped by 'char': 用来设置转义字符符号,默认情况下使用‘\’字符
lines starting by 'char' : 用来设置每行开头的字符符号,默认情况下不使用任何符号
lines terminated by 'string' :用来设置每行结束的字符符号,默认情况下使用'\n'字符串
例:INTO OUTFILE 'F:/1.txt'
FIELDS
TERMINATED by '\、'
ENCLOSED BY '\"'
LINES
STARTING by '\>' 
TERMINATED by '\r\n'
4.4.4文本文件导入到数据表
语法:load data infile filename into table tablename [option];
如果在到处文件中使用了参数选项改变了显示格式,那么导入数据同样需要设置相应参数
例:load dalta infile 'd:/1.txt' into table `result`
FIELDS
TERMINATED by '\、'
ENCLOSED BY '\"'
LINES
STARTING by '\>' 
TERMINATED by '\r\n'
####5.数据库的设计####
 ##5.1设计数据库的步骤
1.收集信息
2.标识实体
3.标识每个实体需要存储的详细信息
4.标识实体之间的关系
 ##绘制ER图
实体:指现实世界中具有区分其他事务的特征或属性并与其它事务有联系的事务,用矩形表示
属性:实体的特征,用椭圆形表示
联系:两个或多个实体之间的关联关系,用菱形表示
2.映射基数
一对一,一对多,多对一,多对多
 ##5.3关系数据库模式
使用二维表的形式表示实体与实体之间联系的数据模型称为关系模型
R(U)
或R(A,B)
R表示关系名,U表示属性集合,A,B代表U中的属性
将ER图转换为关系模式的步骤如下:
1)把每个实体都转化为关系模式R(A,B)形式
2)建立实体间联系的转换
一对一的转换:把任意实体的主键放到另一个实体的关系模式中
一对多的转换:把联系数量为1的实体的主键放到联系数量为N的实体关系模式中
多对多的转换:把两个实体中额主键和联系的属性放到另一个关系模式中
 ##5.4数据规范化
5.4.1规范设计
1.第一范式(1NF)
确保每列的原子性,每列的属性值都是不可再分的最小数据单元
2.第二范式(2NF)
在第一范式的基础上,确保表中的每列都和主键相关,并且除了主键以外的其他列全部依赖于该主键
3.第三范式(3NF)
在第二范式的基础上,确保每列都和主键列直接相关,而不是间接相关,并且除了主键以外的其他列都只能依赖于主键列,列于列之间不存在相互依赖关系
 ##5.5设置外键,使得两张表关联,避免插入无效数据
例:-- 添加外键约束
ALTER table empt  add CONSTRAINT  fk_empt_dept
FOREIGN key (dept_id)
REFERENCES dept (dept_id)
-- 添加级联操作
ALTER table empt  add CONSTRAINT  fk_empt_dept
FOREIGN key (dept_id)
REFERENCES dept (dept_id)
on DELETE CASCADE 
on UPDATE CASCADE
当使用删除操作时,保证两张表级联一起删除相关数据
什么是jar:就是别人将自己写好的类,打包成一个.jar文件
####6.JDBC####
类:DriverManager
接口:Connection
 Statement
 PrepareStatement更安全
 ResultSet
例:
package util;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;


public class DbUtil {
/**
 * 数据库帮助类
 */
public static Connection getConnection(){
String url="jdbc:mysql://localhost:3306/myschoolzhuxinli";
String user="root";
String password="root";
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
public static void main(String[] args) {
System.out.println(DbUtil.getConnection());
}
}


/************************************/
package practise;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


import util.DbUtil;


public class Demo_3_log {
public static void main(String[] args) {
Connection conn=DbUtil.getConnection();
String username="admin";
String password="admin";
PreparedStatement pst=null;
ResultSet rs=null;
try {
// Statement st=conn.createStatement();
// String sql="select * from user where userName='"+
// username+"'and password ='"+password+"'";
// ResultSet rs=st.executeQuery(sql);
//使用preparedstatement更安全
String sql="select * from user where userName=? and password=?";
pst=conn.prepareStatement(sql);
pst.setString(1, username);
pst.setString(2, password);
rs=pst.executeQuery();
//
if(rs.next()){
System.out.println("登录成功");
}

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
conn.close();
pst.close();
rs.close();

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
####7.DAO模式####
 ##7.1异常配置文件
log4j.rootLogger=debug,zy,file
设置输出属性
log4j.appender.zy=org.apache.log4j.ConsoleAppender ##设置输出到控制台
log4j.appender.zy.Target=System.out ##设置输出样式
log4j.appender.zy.layout=org.apache.log4j.PatternLayout
log4j.appender.zy.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n  ##设置输出格式
设置输出到文件
log4j.appender.file=org.apache.log4j.FileAppender ##设置输出到文件
log4j.appender.file.Threshold=error ##只输出异常信息
log4j.appender.file.File=f://test.log ##设置输出路径
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n

public Logger log=Logger.getLogger(SlaveDao.class);调用
 ##使用配置文件properties
调用时使用
Properties properties=new Properties();
//properties.load(new FileInputStream("resourcesdb.properties"));
//通过类路径获得Inputstream资源流
properties.load(DbUtil.class.getClassLoader().getResourceAsStream("db.properties"));
url=properties.getProperty("url");
user=properties.getProperty("username");
password=properties.getProperty("password");
配置信息
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/happgame
username=root
password=root
封装查询
//封装查询
public static Object find(String sql,Object[] params,Class cla) throws Exception{//将数据库中查询的结果存放到对象中,并存放到集合中
List<Object> object=new ArrayList<>();
Connection conn=getConnection();
PreparedStatement ps=conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
ps.setObject((i+1), params[i]);
}
ResultSet rs=ps.executeQuery();
while(rs.next()){
Object obj=cla.newInstance();
int count=rs.getMetaData().getColumnCount();
for (int i = 1; i <= count; i++) {
//获得每一列的字段名==属性名
String columnName=rs.getMetaData().getColumnName(i);
System.out.println(columnName);
//通过反射给对象赋值
Field field=cla.getDeclaredField(columnName);
field.setAccessible(true);
if(rs.getMetaData().getColumnTypeName(i).equalsIgnoreCase("tinyint")){
field.set(obj, rs.getInt(columnName));
}else if(rs.getMetaData().getColumnTypeName(i).equalsIgnoreCase("decimal")){
field.set(obj, rs.getDouble(columnName));
}else if(rs.getMetaData().getColumnTypeName(i).equalsIgnoreCase("Timestamp")){
field.set(obj, rs.getDate(columnName));
}else{

field.set(obj, rs.getObject(columnName));
}
}
lis.add(obj);
}
return object;
}
事务:conn.setAutoCommit(false);
 conn.rollback();
 conn.commit();




#####补充#####
###存储过程###
1.1创建存储过程
CREATE PROCEDURE sp_name
([proc_parameter[,…]])
[characteristic]
Routine_body
 
说明:
Sp_name:存储过程名称,自定义,尽量起一个有意义的名称
([proc_parameter[,…]]):需要接收或者输出的参数
[characteristic]:特性
Routine_body:要执行的代码,写在BEGIN和END中,BEGIN和END类似于函数体的{}
另:分号是提交有提交的意义,可以设置其他符号作为提交 :delimiter 符号
一个简单的存储过程如下
delimiter $$
create PROCEDURE test_d()
BEGIN
SELECT * from student1;
SELECT * from account;
end;
$$
调用存储过程的时候使用语句:call 存储过程名();
1.2存储过程的特点
1.能完成较复杂的判断和运算
2.可编程性强,灵活
3.SQL编程的代码可重复使用
4.执行速度相对快一点
5.减少网络之间数据传输,节省开销
1.3存储过程的声明变量
例:
create PROCEDURE test_e()
BEGIN
DECLARE my_name VARCHAR(10) DEFAULT '';
SET my_name='xxx';
SELECT name into my_name FROM account WHERE id=1;
SELECT my_name;
end;
call test_e();
使用declare 去创建变量,加类型和默认值
使用set去设置变量值,或者使用select 字段 into 变量名 from 表名 where 条件;来将表中的某个字段的值赋值给变量
使用select 变量名;来返回变量值
使用call 存储过程名();来调用存储过程
注意语句之间要有分号
可以有如下语法:
begin
begin
#代码块
end;
begin
#代码块
end;
end;
和java代码的作用域类似;
1.4存储过程的传参
使用in在(可写可不写)
例:create PROCEDURE test_a(in my_id int)
BEGIN
DECLARE my_name VARCHAR(10) DEFAULT '';
SELECT  name INTO my_name from account WHERE id=my_id;
SELECT my_name;
end;
CALL test_a(3);
使用out修饰参数
例:
create PROCEDURE test_a(in my_id int,out my_name varchar(10))
BEGIN
SELECT  name INTO my_name from account WHERE id=my_id;
SELECT my_name;
end;
调用时:
set @test:='';
CALL test_a(3,@test);
SELECT @test;
在使用调用存储过程时不可使用declare来声明变量,必须使用set来声明一个局部变量,变量名前面加一个@符号,表示局部变量
一个@是由用户自己声明的局部变量,,,而2个@@开头的是系统里面的全局变量
如果需要传入和传出同时时,使用inout类型
注意: mysql中变量不用事前申明,在用的时候直接用“@变量名”使用就可以了。
第一种用法:set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量
第二种用法:select @num:=1; 或 select @num:=字段名 from 表名 where ……
注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”
使用inout传入和传出值
例:
create PROCEDURE test_a(inout my_id int,inout my_name varchar(10))
BEGIN
SELECT  name INTO my_name from account WHERE id=my_id;
end;
调用时:
set @my_id=1;
set @my_name='';
CALL test_a(@my_id,@my_name);
SELECT @my_id as id,@my_name as name ;
注意:可变变量inout:调用时刻传入值,在调用过程中可以修改其值,同时也可返回值
  inout参数集合了in和out类型的参数功能
  inout调用时传入的是变量,而不是常量
1.5if条件语句
语法:if()then...else...end if;
 if()then...elseif()then...else...end if;
例:
create procedure test_b(in my_test INT)
BEGIN
DECLARE my_name VARCHAR(10) DEFAULT '';
if(my_test%2=0)
THEN 
SELECT name INTO my_name from account WHERE id=my_test;
SELECT my_name;
ELSE
SELECT my_test;
end if;
end;
调用:
set @test=2;
call test_b(@test);
1.6循环语句
语法:while()do 
begin..
end; 
end while;
例:
create PROCEDURE test_d()
BEGIN
DECLARE num int DEFAULT 3;
WHILE(num<10) DO
BEGIN
SET num=num+1; #修改num值的时候必须使用set来修改
 INSERT INTO account(id) VALUES(num);
END;
end WHILE;
SELECT * from account ;
end;
调用:
CALL test_d();
repeat 循环:
语法:repeat 
begin ... end;
until ... 
end repeat;
create PROCEDURE test_d()
BEGIN
DECLARE num int DEFAULT 10;
REPEAT
BEGIN
SET num=num+1;
 INSERT INTO account(id) VALUES(num);
END;
UNTIL num>=20
end REPEAT;
SELECT * from account ;
end
调用 :
CALL test_d();
1.7游标
例:create PROCEDURE test_cur()
BEGIN
DECLARE stop_flag int DEFAULT 0;
DECLARE my_name VARCHAR(10) DEFAULT '';
DECLARE my_cur CURSOR for SELECT name from account WHERE id%2=0;
#1.游标是保存查询结果的临时内存区域
#2.游标变量my_cur保存了查询的临时结果,实际上就是查询结果集
DECLARE CONTINUE HANDLER  for NOT found set stop_flag=1;
#3.当游标变量中保存的结果都查询一遍(遍历),到达结尾把变量stop_flag设置为1
#用于循环中判断是否结束

OPEN my_cur;#打开游标
FETCH my_cur into my_name;#游标向前走一步,取出一条记录放到变量my_name中。
while(stop_flag=0) DO#如果游标还没有到结尾,就继续
BEGIN
UPDATE account SET name=CONCAT(my_name,'_cur')WHERE `name`=my_name;
FETCH my_cur into my_name;
END;
END WHILE;
CLOSE my_cur;
END
####2.函数####
2.1创建函数
例:create FUNCTION test_t(my_id int )
RETURNS VARCHAR(10) Reads sql data
BEGIN
DECLARE my_name VARCHAR(10) DEFAULT '';
SELECT name into my_name from account WHERE id=my_id;
return my_name;
end;
调用:select test_t(1);
高级中自定义访问类型:1)只能读:reads sql data
 2)查询sql语句:contains sql
 3)没有sql的语句:no sql
 4)在函数中对数据进行修改:modifies sql data
CREATE FUNCTION  func_name ([func_parameter[…]])
RETURNS type
[characteristic…]
Routine_body
 
说明:
RETURN type:表示返回值的类型
[characteristic…]:表示函数的特性,与存储过程的特性一致
查看函数
查看存储过程:SHOW PROCEDURE STATUS LIKE ‘sp_name’;
查看存储函数:SHOW FUNCTION STATUS LIKE ‘func_name’;
查看全部存储过程:SHOW PROCEDURE STATUS \G
查看全部存储函数:SHOW FUNCTION STATUS \G
 
注意:‘sp_name’和‘func_name’一定要加引号。

####3.触发器####
##3.1简单的触发器
例:create TRIGGER ·add_master· AFTER INSERT on `master`
for EACH ROW
BEGIN
INSERT into ·test· VALUES(new.master_id,new.username);
end;
new:表示插入的对象,更新之后
old:表示更新之前的对象
 1.创建触发器使用create trigger触发器名
 2.什么时候触发?可以是after,可以是before
 3.对什么操作事件触发?操作事件包括insert,update ,delete
 4.对什么表触发on 表名
 5.影响的范围?for each row







 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值