MySQL自增列的步長問題
-
惟一索引和聯合惟一
-
外鍵的變種
-
SQL數據行的增刪改查
-
視圖
-
觸發器
-
函數
-
存儲過程
-
事務
-
遊標
-
動態執行SQL(防SQL注入)
1.MySQL自增列的步長問題:
1.基於會話級別(單次登錄狀態下):
show session variables like 'auto_inc%';
#查看自增加的默認步數,通常爲1
set session auto_increment_increment=2;
#設置自增加會話步長爲2
set session auto_increment_offset=10; #設置默認自增加初始值
2.基於全局級別(全部用戶生效):
show global variables like 'auto_inc%'; #查看全局變量中的自增加的默認步長
set global auto_increment_increment=2; #設置全局會話步長
set global auto_increment_offset=10; #設置全局自增加初始值
2.惟一索引和聯合惟一:
create table t1(
id int,
num int,
name char
unique uql (num) #惟一索引
unique uql (num, name) #聯合惟一
);
惟一索引和主鍵 的共同點:
1.都有加速查找的功能;
2.都是惟一,不能重複
惟一索引和主鍵的不一樣點:
主鍵既不能重複也不能爲空;
而惟一索引不能重複,可是
能夠有值爲空,好比聯合索引中能夠設置一個值爲null
3.外鍵的變種:
1.一對一:博客用戶表
2.一對多:百合網相親記錄表
3.多對多:用戶主機關係表
4.SQL數據行的增刪改查:
增:
insert into test(name, age) values('name', 18);
insert into test(name, age)
values('name1', 18),('name2', 18); #一次性插入多個值
insert into test(name, age)
select name,age from test1; #把某張表中的數據插入
刪:
delete from test;
delete from test where id>2
and name='name1';
改:
updata test set name='name2',age=19 where id>12 and name='name1';
查:
select * from test;
select id,name from test where id>2;
select name,age,
123 from test;
select
name as rname from test;
select * from test
where id in (1,3,5,7);
select * from test
where id in (select id from test1);
select * from test
where id between 5 and 9; #閉區間,左右均可以取到
通配符
select * from test
where name like 'name%'; %匹配無數字符;_匹配一個字符
分頁
select * from test
limit 10; 取前十條
select * from test
limit 0,10; 表示從0開始,取0後面的10條
select * from test
limit 10 offset 20; 表示從20開始,取20後的前10條
排序
select * from test
order by id desc; id從大到小排列
select * from test
order by id asc; id從小到大排列
select * from test order by age desc, id asc; 多個不一樣排序
select * from test order by desc limit 10; 取後十條
分組(聚合函數:count,max,min,sum,avg求平均值)
select max(id),id from test group by sex; 若是遇到相同的sex,只會取最大id的
select count(id),id from test group by sex; 計數
select count(id) as count,id form test group by sex;
select count(id),id from test group by sex having count(id)>2;
對於聚合函數結果進行二次篩選時,必須使用having
連表操做:
#左右連表 join
select * from
test1,test2 where test1.id = test2.part_id;
select * from test1
left join test2 on test1.id = test2.part_id; test1左邊會所有顯示
select * from test
right
join
test2 on test1.id = test2.part_id; test1右邊會所有顯示
select * from test
innder
join
test2 on test1.id = test2.part_id; 會把出現null的那一行隱藏
#上下連表 union
select id,name from test1
union #
自動去重
select id,name from test2;
select id,name from test1
union all #不去重
select id,name from test2;
轉儲mysql文件:
mysqldump -uroot test1 > test1.sql -p #數據表結構+數據
mysqldump -uroot -d test1 > test1.sql -p #只有數據表結構
導入mysql文件:
create databases test1;
mysqldump -uroot -d test1 < test1.sql -p;
臨時表
select id from (select id from test where num>60) as B;
添加條件
select min(num),min(num)+1,
case when num<10 then 0 else min(num) end from score
#建立
create view as view1 select * from test where id>10;
#視圖是一個臨時表
#
視圖是虛擬出來的,不是物理表,所以不能插入數據
#修改
alter view 視圖名稱 as SQL
6.觸發器:
#插入前
create trigger t1
BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(NEW.sname)
;
END
#插入後 after insert
#刪除前 before delete
#刪除後 after delete
#更新前 before update
#更新後 after update
#因爲默認;結束,所以不會執行end,因此要執行觸發器以前要
先修改終止符
delimiter //
create trigger t1 BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(sname);
END //
delimiter ;
#建立時自動插入:
drop trigger t1; #結束上一個觸發器
delimiter //
create trigger t1 BEFORE INSERT on student for EACH ROW
BEGIN
INSERT into teacher(tname) values(
NEW.sname);
END //
delimiter ;
insert into student(gender,class_if,sname) values('女',1,'abc')
#自定義函數(有返回值)
#建立函數
delimiter \\
create function f1(
i1 int,
i2 int)
returns int
BEGIN
declare num int; 聲明一個變量類型是整數
set num = i1 + i2;
return(num);
END \\
delimiter ;
#運行函數
select f1(1,100);
1.簡單存儲過程
delimiter //
create PROCEDURE p1()
BEGIN
select * from student;
insert into teacher(tname) values('ct');
END
delimiter ;
#調用存儲過程
call p1;
cursor.callproc('p1')
2.傳參數(in,out,inout)
delimiter //
create PROCEDURE p2(
in n1 int,
in n2 int
)
BEGIN
select * from student where sid>n1;
END
#調用
call p2(12,2);
cursor.callproc('p2',(12,2))
delimiter //
create PROCEDURE p2(
in n1 int,
out n2 int #out假裝返回值
)
BEGIN
set n2 = 123123;
select * from student where sid>n1;
END
#調用
set @vi = 0 #建立了一個session級的變量叫作v1,能夠在外部接收
call p2(12,@v1)
select @v1; 接收變量
cursor.execute('select @_p2_0,@_p2_1') #pymysql中接收存儲過程變量
存儲過程的特性:
a.可傳參 (in out inout)
b.pymysql
爲何有結果值又有out僞造的返回值:
out的做用:用於標識存儲過程的執行結果,如1爲失敗,2爲成功,3爲局部成功
9.事務:
delimiter //
create procedure p4(
out status int
)
BEGIN
1.聲明若是出現異常則執行{
set status = 1;
rollback; #回滾
}
開始事務
--a帳戶減小100
--b帳戶增長100
commit;
結束
set status = 2;
#若是這裏的事務執行順利,會獲得變量等於2,不會執行回滾
END //
delimiter ;
delimiter \\
create PROCESDURE p1(
out p_return_code tinyint
)
BEGIN
declare exit handler for sqlexception #這樣代碼的意思是若是沒有順利執行,就執行下面的代碼
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
START TRANSACTION;
DELETE from tb1;
insert into tb2(name) values('seven');
COMMIT;
--SUCCESS
set p_return_code = 0;
END\\
delimiter ;
#正確的返回0,錯誤的返回1
10.遊標:
delimiter //
create procedure p6()
begin
declare row_id int; --自定義變量1
declare row_num varchar(50); --自定義變量2
declare done INT DEFAULT FALSE;
declare my_cursor CURSOR FOR select id,num from A;
declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
open my_cursor; #打開遊標
xxoo: LOOP #開始循環
fetch my_cursor into row_id,row_num; #取一行數據賦值給row_id和row_num
if done then
leave xxoo;
END IF;
insert into teacher(tname) values(ssname);
end loop xxoo; #終止循環
close my cursor; #關閉遊標
end //
delimter;
delimiter //
create procefure p7(
in tpl varchar(255),
in arg int
)
begin
1.預檢測某個東西,SQL語句合法化
2.SQL = 格式化 tp+arg
3.執行SQL語句
set @x0 = arg; #聲明變量
PREPARE(準備)
XXX(變量)
FROM 'select * from student where sid > ?';
EXECUTE(執行)
xxx USING @arg(替換上面的?);
DEALLOCATE prepare prod;(執行已經格式化完成的SQL語句)
end //
delimter;
call p7('select * from tb where id > ?',9)
delimiter \\
CREATE PROCEDURE p8 (
in nid int
)
BEGIN
set @nid = nid;
PREPARE prod FROM 'select * from student where sid > ?';
EXECUTE prod USING @nid;
DEALLOCATE prepare prod;
END\\
delimiter ;