ALTER TABLE stuinfo Drop primary key;
ALTER TABLE stuinfo drop index seat;
alter table stuinfo drop foreign key fk_stuinfo_major;
alter table emp2 add column dept_id int;
alter table emp2 add constraint fk_emp2_depts foreign key(dept_id) references dept2(id);
CREATE TABLE tab_identity(
id int PRIMARY key auto_increment,
name VARCHAR(20)
);
INSERT into tab_identity values(null,'john');
不一定,但是要求是一个key,即为主键或者unique;
最多只能有一个。
alter table tab_identity modify column id int primary key auto_increment;
Transaction Control Language事务控制语言
1.一个或一组sql语句组成的一个执行单元,这个执行单元要么全部执行,要么全部不执行。
2.为了确保相互影响的sql语句操作的完整性。
show engines;
1.隐式创建:事务没有明显的开启和结束的标签
2.显式事务:事务具有明显的开启和结束的标记。必须先设置自动提交功能为禁用。命令为:set autocommit=0;
查看事务是否关闭的语句:
show variables like 'autocommit';
步骤:
1.开启事务
set autocommit=0;
start transaction;
2.编写事务中的sql语句
3.结束事务
commit;提交事务
rollback;回滚事务
1.脏读:对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段.之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
2.不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段.之后, T1再次读取同一个字段, 值就不同了.
3.幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.
数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响, 避免各种并发问题.
1.Oracle 支持的 2 种事务隔离级别:READ COMMITED,SERIALIZABLE。 Oracle 默认的事务隔离级别为: READCOMMITED
2.Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ
select @@tx_isolation;
set session transaction isolation level read committed
set global transaction isolation level read committed;
set autocommit=0;
start transaction;
delete from account where id=25;
savepoint a;
delete from account where id=28;
rollback to a;
MySQL从5.0.1版本开始提供视图功能。一种虚拟存在的表,行和列的数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的,只保存了sql逻辑,不保存查询结果
– 多个地方用到同样的查询结果
– 该查询结果使用的sql语句较复杂
CREATE VIEW my_v1
AS
SELECT studentname,majorname
FROM student s
INNER JOIN major m
ON s.majorid=m.majorid
WHERE s.majorid=1;
方式一:
create or replace view 视图名
as
查询语句;
方式二:
alter view 视图名
as
查询语句;
drop view 视图名,视图名
Desc 视图名
show create view 视图名;
use myemployees;
create or REPLACE view emp_v1
as
select last_name,salary,email
from employees
where phone_number like '001%'
1.包含以下关键字的sql语句:分组函数、distinct、group by、having、union或者union all
2.常量视图
3.select中包含子查询
4.使用到了join语句
5.from后面跟的是一个不能更新的视图
set autocommit=0;
start transaction;
delete from account;
rollback;
alter table stuinfo add constraint fk_stu_major foreign key(majorid) references major(id) on delete cascade;
alter table stuinfo add constraint fk_stu_major foreign key(majorid) references major(id) on delete set null;
系统变量:全局变量、会话变量
自定义变量:用户变量、局部变量
说明:变量由系统提供,不是用户定义,属于服务器层面
使用的语法:
1.查看所有的系统变量
show global variables;
2.查看会话变量
show session variables;
3.查看满足条件的部分系统变量
global|[session] variables like ‘%char%’
4.查看指定的某个系统变量的值
select @@global|session.系统变量名;
5.为某个系统变量赋值
set global|session 系统变量名=值;
set @@global|[session].系统变量名=值;
注意:
如果是全局级别,则需要加global,如果是会话级别,则需要加session,如果不写,则默认是session
作用域:服务器每次重启将为所有的全局变量赋初始值,针对所有的会话(连接)有效,但是不能跨重启
仅仅针对于当前会话(连接)有效
针对当前会话(连接)有效,同于会话变量的作用域
可以放在任何地方
方式一:
set @用户变量名=值;
set @用户变量名:=值;
set @用户变量名:=值;
方式二:
select 字段 into @变量名
from 表;
案例:
#声明并初始化
set @name='john';
set @name=100;
set @count=1;
#赋值
select count(*) into @count
from employees;
#查看
select @count;
作用域:仅仅在定义它的begin end中有效,应用在begin end中的第一句话
1.声明
declare 变量名 类型;
declare 变量名 类型 default 值;
2.赋值
方式一:通过set或select
set 局部变量名=值;
set 局部变量名:=值;
select @局部变量名:=值;
方式二:通过select into
select 字段 into 局部变量名
from 表;
3.使用
select 局部变量名;
含义:一组预先编译好的SQL语句的集合,理解成批量处理语句
1.提高代码的重用性
2.简化操作
3.减少了编译次数并且减少了和数据据服务器的连接次数,提高了效率
create procedure 存储过程名(数据列表)
begin
存储过程体(一组合法的sql语句)
end
注意:参数列表包含三部分
参数模式 参数名 参数类型
举例:
IN stuname varchar(20)
参数模式:
in:该参数可以作为输入
out:输出
inout:输入输出
存储过程体
如果存储过程体仅仅只有一句话,begin end可以省略;
存储过程体中的每条sql语句的结尾要求必须加分号。
存储过程的结尾可以使用delimiter重新设置
语法:
delimiter 结束标记
delimiter $
call 存储过程名(实参列表)
use students;
select * from major;
delimiter $
CREATE PROCEDURE myp1()
BEGIN
insert into major values(1,"1"),(2,"2"),(3,"3"),(4,"4");
end $
call myp1() $
create PROCEDURE myp2(in beautyName VARCHAR(20))
begin
select bo.*
from boys bo
right join beauty b on bo.id=b.boyfriend_id
where b.name=beautyName;
end $
call myp2('柳岩') $
create PROCEDURE myp4(in username VARCHAR(20),in password VARCHAR(20))
BEGIN
DECLARE result int default 0;
select count(*) into result
from admin
where admin.username=username
and admin.password=PASSWORD;
select if(result>0,'成功','失败');
END $
call myp4('张飞','8888') $
delimiter $
CREATE PROCEDURE myp5(in beautyName varchar(20),out boyName VARCHAR(20))
BEGIN
select bo.boyName into boyName
from boys bo
INNER JOIN beauty b on bo.id=b.boyfriend_id
where b.name=beautyName;
END $
call myp5('小昭',@bName) $
select @bName$
create PROCEDURE myp6(in beautyName varchar(20),out boyName VARCHAR(20),out userCP int)
BEGIN
select bo.boyName,bo.userCP into boyName,userCP
FROM boys bo
INNER JOIN beauty b on bo.id=b.boyfriend_id
where b.name=beautyName;
END $
call myp6('小昭',@bName,@usercp)$
select @bName,@usercp
create PROCEDURE myp8(INOUT a int,inout b int)
BEGIN
set a=a*2;
set b=b*2;
END $
set @a=10$
set @b=10$
call myp8(@a,@b)$
select @a,@b$
CREATE PROCEDURE test_pro1(in username varchar(20),in loginPwd VARCHAR(20))
BEGIN
insert into admin(admin.username,PASSWORD)
values(username,loginPwd);
END $
create PROCEDURE test_pro2(in id int,out name VARCHAR(20),out phone VARCHAR(20))
BEGIN
select b.name,b.phone into name,phone
from beauty b
where b.id=id;
END $
call test_pro2('1')$
create PROCEDURE test_pro3(in birth1 datetime,in birth2 datetime,out result int)
BEGIN
select DATEDIFF(birth1,birth2) into result;
end $
drop procedure p1;
show create PROCEDURE myp2;
CREATE PROCEDURE test_pro4(in mydate datetime,out strDate VARCHAR(50))
BEGIN
select DATE_FORMAT(mydate,'%y年%m月%d日') into strDate;
END $
call test_pro4(now(),@str)$
select @str $
create PROCEDURE test_pro5(in beautyName varchar(20),out str VARCHAR(50))
BEGIN
select concat(beautyName,' and ',ifnull(boyName,'null')) into str
from boys bo
RIGHT JOIN beauty b on b.boyfriend_id=bo.id
where b.name=beautyName;
END $
call test_pro5('小昭',@str)$
select @str $
存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
函数:有且仅有1个返回值,适合做处理数据后返回一个结果
create function 函数名(参数列表) returns 返回类型
begin
函数体
end
注意:
1.参数列表 包含两部分:
参数名 参数类型
2.函数体:肯定会有return语句,如果没有会报错
如果return语句没有放在函数体的最后也会报错,但是不建议
return 值;
3.函数体中仅有一句话则可以省略begin end
4.使用delimiter语句作为设置结束标志
select 函数名(参数列表)
use myemployees
delimiter $
CREATE FUNCTION myf1() RETURNs INT
BEGIN
DECLARE c int default 0;
select count(*) into c
from employees;
return c;
END $
select myf1()$
create function myf2(empName VARCHAR(20)) returns double
BEGIN
set @sal=0;
select salary into @sal
from employees
where last_name=empName;
return @sal;
end $
select myf2('kochhar') $
CREATE FUNCTION myf3(deptName VARCHAR(20)) returns double
BEGIN
DECLARE sal double;
select avg(salary) into sal
from employees e
join departments d on e.department_id=d.department_id
where d.department_name=deptName;
return sal;
END $
select myf3('IT')$
show create function myf3;
drop function myf3;
create function test_fun1(num1 float,num2 float) returns float
begin
declare sum float default 0;
set sum=num1+num2;
return sum;
end $
select test_fun1(1,2)$
顺序结构
分支结构
循环结构
if(表达式1,表达式2,表达式3)
表达式1成立执行表达式2不成立则执行表达式3
语法:
情况1:
case 变量|表达式|字段
when 要判断的值 then 返回的值1或语句1;
when 要判断的值 then 返回的值2或语句2;
…
else 要返回的值n或语句n;
end
情况2:
case
when 要判断的条件1 then 返回的值1或语句1;
when 要判断的条件2 then 返回的值2或语句2;
…
else 要返回的值n或语句n;
end
特点:
可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,begin end中或begin end的外边
可以作为独立的语句去使用,只能放在begin end中。
ELSE可以省略,如果ELSE省略了,并且所有WHEN条件都不满足,则返回null.
delimiter $
create PROCEDURE test_case(in score int)
BEGIN
case
when score>=90 and score<=100 then select 'A';
when score>=80 then select 'B';
when score>=60 then select 'C';
else select 'D';
end case;
END $
call test_case(95)$
语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
…
[else 语句n;]
end if;
应用在begin end中
create function test_if(score int) returns CHAR
BEGIN
if score>=90 and score<=100 then RETURN 'A';
ELSEIF score>=80 then return 'B';
ELSEIF score>=60 then return 'C';
else RETURN 'D';
end if;
END $
select test_if(10)$
语法:
[标签:]while 循环条件 do
循环体;
end while [标签];
[标签:] loop
循环体;
end loop [标签];
[标签:]repeat
循环体;
until 结束循环的条件
end repeat [标签];
create PROCEDURE pro_while(in insertCount int)
BEGIN
DECLARE i int DEFAULT 1;
while i<=insertCount DO
INSERT into admin(username,`PASSWORD`) values(concat('Rose',i),'666');
set i=i+1;
end while;
END $
call pro_while(100)$
CREATE PROCEDURE test_while2(in insertCount int)
BEGIN
DECLARE i int default 1;
a:while i<insertCount DO
delete from admin WHERE username=CONCAT('Rose',i);
if i>=20 then leave a;
end IF;
set i=i+1;
end while a;
END $
call test_while2(100)$
create procedure test_while3(in insertCount int)
BEGIN
DECLARE i int DEFAULT 0;
a:WHILE i<=insertCount DO
set i=i+1;
if mod(i,2)!=0 then ITERATE a;
end if;
INSERT into admin(username,`password`) values(concat('xiaohua',i),'0000');
end while a;
END $
call test_while3(100)$
create table stringcontent(
id int PRIMARY key auto_increment,
content varchar(20)
);
delimiter $
CREATE PROCEDURE test_randstr_insert(in insertCount int)
BEGIN
DECLARE i int default 1;
DECLARE str VARCHAR(26) DEFAULT 'abcdefghijgkmnopqrstuvwxyz';
DECLARE startIndex int DEFAULT 1;
DECLARE len int DEFAULT 1;
WHILE i<insertCount DO
set len=floor(rand()*(20-startIndex+1)+1);
set startIndex=floor(RAND()*26+1);
insert into stringcontent(content) values(SUBSTR(str,startIndex,len));
set i=i+1;
end while;
END $
call test_randstr_insert(2)$