mysql存儲過程筆記(易查閱)


left join 左右連表

union 上下連表 自動去重 + all 不會去重

select * from t1
union
select * from t0;

1.視圖

臨時表 要有100sql語句一直都要使用這個語句

反覆存在 就可以取一個別名 根據別名做操作 :視圖的名稱

create view v1 as select * from t0;  #視圖就叫做 v1
alter view v1 sql
drop view v1

視圖中可以進行插入數據

視圖:虛擬表 本質上不可以進行修改

不常用 ,如果寫視圖在開發中 別人在接管時看不懂

2.觸發器

某個操作執行之後觸發 相當於裝飾器

當對某張表做:增刪改時,可以使用觸發器自定義關聯行爲

insert into db() values();
用戶註冊一個,日誌再去存儲所有的信息

插入前
create trigger adf defore insert on tb1 for each row
begin
insert into tb2() values()
----------------------
----------------------
end

create trigger adf after insert on tb1 for each row
begin
insert into tb2() values()
end

刪除前
create trigger adf defore delete insert on tb1 for each row
begin
insert into tb2() values()
end

create trigger adf after after delete on tb1 for each row
begin
insert into tb2() values()
end

更新前
create trigger adf after before update on tb1 for each row
begin
insert into tb2() values()
end

create trigger adf after after update on tb1 for each row
begin
insert into tb2() values()
end

每插入一行數據,就會觸發插入一條數據

new   代指新數據

old   代指老數據
create trigger adf defore insert on tb1 for each row
begin
insert into tb2(tname) values(new.sname)  #表示新插入的數據
end

insert into tb1(sname) values('bon'),('hello') 同時插入到 tb1 tb2中

在mysql 中改變終止符 delimiter //

數據庫級別

3.函數

聚合函數 max, min ,count ,avg ,sum, case when if else

內置函數:

​ 執行函數:

blog表

id title ctime
1 a 2019-11-11 11:11
2 b 2019-10-11 11:11
3 c 2019-10-11 01:11

如果我們想讓blog的文章按照月份進行分組,就需要用到 date_format函數將日期變成年月進行分組


select ctime,count(1) from blog group by ctime
select ctime,count(1) from blog group by date_format(ctime,"%Y-%m") --變成年月。到內存中進行分組

select char_length('asd'); --字符長度
select concat('hello','world'); --字段串拼接

還有很多內置函數可以查看官網

自定義函數:有返回值

DELIMITER / 定義結束符。MySQL默認的結束符是分號,但是函數體中可能用到分號。爲了避免衝突,需要另外定義結束符。

delimiter //
create function f1(
	i1 int,
	i2 int
)
returns int  #返回值的類型 頭部執行完畢
begin       #函數體
	declare num int default 0;    #聲明變量 num = 0
	set num = i1 + i2;   
	return (num);
end //
弱類型語言
delimiter ;

[報錯處理](https://blog.csdn.net/qq_43058911/article/details/102677088)

4.存儲過程

存儲過程:保存在msyql上的一個別名,很多sql語句,

自己使用別名() 查詢結果

視圖與存儲過程的區別

視圖:是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含一系列帶有名稱的列和行數據。但是,視圖並不在數據庫中以存儲的數據值集形式存在

存儲過程: 別名()  很多sql語句操作,可以大大節省程序員寫sql語句
優點:將代碼和sql語句耦合 DBA維護存儲過程

delimiter //
create procedure pq()  #創建一個存儲過程
begin
    select * from student;
    insert into teacher(tname) values("小小")
end //
delimiter ;

call pq(); 執行完畢直接查詢到想要的內容
視圖是通過: 
create view v1 as select * from t0;
select v1 ; 進行調用

在Pymysql中通過 cursor.callproc(‘pq’) 取出數據

需求:我們怎樣通過pymysql 來與 存儲過程進行交互的存取數據呢?

可以通過存儲過程名中的參數 (in , out ,inout)

in : 輸入參數:表示調用者想過程中傳入值(傳入值可以是字面量或者變量)


delimiter //
create procedure pq(
	in n1 int,
	in n2 int
)   
begin
    select * from student where id > n1;
    insert into teacher(tname) values("小小")
end //
delimiter ;

call pq(12,2) #第二個沒有使用但是必須要傳遞
cursor.callproc('pq',(12,2))  #在python中的查詢

out : 輸出參數,表示過程向調用者傳出值(可以返回多個值)(傳出值只能是變量)

不接受輸入的參數


delimiter //
create procedure pq(
	in n1 int,
	out n2 int
) 
begin
    select * from student where id > n1;  --  不會執行 
    set n2 = 2
    select * from student where id > n2;  
end //
delimiter ;

set @n2 = 0;  -- 創建一個session級別的變量
call pq(12,@n2)
select @n2  -- 2

@n2 = 123123   --外部可以獲取到
cursor.callproc('pq',(12,3))  --任意輸入,反正裏面不接受
r1 = cursor.fetchall()
print(r1)
cursor.excute('select @_pq_0,@_pq_1') --第二次查詢
r2 = cursor.fetchall()
print(r2)


inout:輸入輸出參數,既表示調用者向過程傳入值,又表示過程向調用者傳出值(值只能是變量)


delimiter //
create procedure pq(
	inout n1 int,
)   
begin
    select * from student where id > n1;  -- id > 3
    set n1 = 2
    select * from student where id > n1;  -- id > 2
end //
delimiter ;

set @n1 = 3; --相當於從外部傳遞的變量
call pq(@n1);
select @n1;  2

mysql的事務

事務(Transaction)是一個操作序列,不可分割的工作單位,以BEGIN TRANSACTION開始,以ROLLBACK/COMMIT結束

特性(ACID):
原子性(Atomicity):邏輯上是不可分割的操作單元,事務的所有操作要麼全部提交成功,要麼全部失敗回滾(用回滾日誌實現,反向執行日誌中的操作);
一致性(Consistency):事務的執行必須使數據庫保持一致性狀態。在一致性狀態下,所有事務對一個數據的讀取結果都是相同的;
隔離性(Isolation):一個事務所做的修改在最終提交以前,對其它事務是不可見的(併發執行的事務之間不能相互影響);
持久性(Durability):一旦事務提交成功,對數據的修改是永久性的

mysql事務流程



delimiter //
create procedure pq(
	out status int
) 
begin
1.聲明如果出現異常則執行{
	set status = 1 --可以監測到
	rollback;   --回滾
}
--開始事務
     -----A賬戶 -100元
     -----B賬戶 +100元
     commit;
結束
set status = 2; 
end //
delimiter ;

--如果拿到2就說明成功了

實例:
delimiter //
create procedure pq(
	out status int
) 
begin
declare exit handler for sqlexception
	begin
		-- error
		set status = 1;
		rollback;
	end;

	start transaction;
		delete from tb1;
	commit
     
     -- success
     set status = 2;
end //
delimiter ;


需求:

將A表中所有數據導入B表,B中的Num是A中的 id + num 的值
思路:循環A中的每一行
1.聲明一個遊標
2.獲取A表中想要的數據,打開文件進行循環

A

id num
1 3
2 4
3 2

B

id num
1 4
2 6
3 5
delimiter //
create procedure pq()
begin
    declare row_id int;
    declare row_num int;
    declare done int default false;
    declare temp int;    --聲明變量

    declare A_cursor cursor for select id,num from A;   --創建遊標
    declare continue handler for not found set done = true;     --如果沒有數據done 爲真則退出 

    open A_cursor;  --打開數據
        xxoo:loop
            fetch A_cursor into row_id ,row_num;   --去遊標裏面拿一行數據複製給row_id,row_num
            if done then
                leave xxoo; --如果爲true跳出循環
            end if;
            set temp = row_id + row_num;
            insert into B(num) values(temp);
        end loop xxoo;
    close A_cursor;

end //
delimiter ;

如果在行中需要操作,在用遊標,一般不適用,因爲效率低

動態執行sql(防止sql注入)

delimiter //
create procedure pq(
	in n1 varchar(100),
	in arg int
)
begin
	-- 預檢測某個東西 sql語句的合法性
	-- sql = 格式化 n1 + arg
	-- 執行sql語句
	
	set @xo = arg;  --設置一個會話級別
	prepare xxx from 'select * from student where sid > ?'; --先檢測,防止sql注入
	execute xxx using @xo;
	deallocate prepare prod;
end //
delimiter ;

call pq("select * from student where sid > ?",9)

5.索引

delimiter //
create procedure pq(
	in n1 varchar(100),
	in arg int
)
begin
	-- 預檢測某個東西 sql語句的合法性
	-- sql = 格式化 n1 + arg
	-- 執行sql語句
	
	set @xo = arg;  --設置一個會話級別
	prepare xxx from 'select * from student where sid > ?'; --先檢測,防止sql注入
	execute xxx using @xo;
	deallocate prepare prod;
end //
delimiter ;

call pq("select * from student where sid > ?",9)

5.索引

待補充!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章