MySQL存儲(chǔ)過(guò)程的創(chuàng)建使用以及實(shí)現(xiàn)數(shù)據(jù)快速插入
一,存儲(chǔ)過(guò)程介紹
自MySQL 5.0 版本開(kāi)始支持存儲(chǔ)過(guò)程。存儲(chǔ)過(guò)程(Stored Procedure)是一種在數(shù)據(jù)庫(kù)中存儲(chǔ)復(fù)雜程序,以便外部程序調(diào)用的一種數(shù)據(jù)庫(kù)對(duì)象。
存儲(chǔ)過(guò)程是為了完成特定功能的SQL語(yǔ)句集,經(jīng)編譯創(chuàng)建并保存在數(shù)據(jù)庫(kù)中,用戶可通過(guò)指定存儲(chǔ)過(guò)程的名字并給定參數(shù)(需要時(shí))來(lái)調(diào)用執(zhí)行。
存儲(chǔ)過(guò)程思想就是數(shù)據(jù)庫(kù) SQL 語(yǔ)言層面的代碼封裝與重用。類似于Java開(kāi)發(fā)中封裝工具類方便以后直接調(diào)用的作用。
二,存儲(chǔ)過(guò)程的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 存儲(chǔ)過(guò)程可以一次編譯多次使用。存儲(chǔ)過(guò)程只在創(chuàng)建時(shí)進(jìn)行編譯,之后的使用都不需要重新編譯,k就提升了sQL的執(zhí)行效率。
- 可以減少開(kāi)發(fā)工作量。將代碼封裝成模塊,實(shí)際上是編程的核心思想之一,這樣可以把復(fù)雜的問(wèn)題拆解成不同的模塊,然后模塊之間可以重復(fù)使用,在減少開(kāi)發(fā)工作量的同時(shí),還能保證代碼的結(jié)構(gòu)清晰。
- 存儲(chǔ)過(guò)程的安全性強(qiáng)。我們?cè)谠O(shè)定存儲(chǔ)過(guò)程的時(shí)候可以設(shè)置對(duì)用戶的使用權(quán)限,這樣就和視圖一樣具有較強(qiáng)的安全性。
- 可以減少網(wǎng)絡(luò)傳輸量。因?yàn)榇a封裝到存儲(chǔ)過(guò)程中,每次使用只需要調(diào)用存儲(chǔ)過(guò)程即可,這樣就減少了網(wǎng)絡(luò)傳輸量。
- 良好的封裝性。在進(jìn)行相對(duì)復(fù)雜的數(shù)據(jù)庫(kù)操作時(shí),原本需要使用一條一條的sQL語(yǔ)句,可能要連接多次數(shù)據(jù)庫(kù)才能完成的操作,現(xiàn)在變成了一次存儲(chǔ)過(guò)程,只需要連接一次即可。
缺點(diǎn)
- 可移植性差。存儲(chǔ)過(guò)程不能跨數(shù)據(jù)庫(kù)移植,比如在MysQL、Oracle和sQL Server里編寫的存儲(chǔ)過(guò)程,在換成其他數(shù)據(jù)庫(kù)時(shí)都需要重新編寫。
- 調(diào)試?yán)щy。只有少數(shù)DBMS支持存儲(chǔ)過(guò)程的調(diào)試。對(duì)于復(fù)雜的存儲(chǔ)過(guò)程來(lái)說(shuō),開(kāi)發(fā)和維護(hù)都不容易。雖然也有一些第三方工具可以對(duì)存儲(chǔ)過(guò)程進(jìn)行調(diào)試,但要收費(fèi)。
- 存儲(chǔ)過(guò)程的版本管理很困難。比如數(shù)據(jù)表索引發(fā)生變化了,可能會(huì)導(dǎo)致存儲(chǔ)過(guò)程失效。我們?cè)陂_(kāi)發(fā)軟件的時(shí)候往往需要進(jìn)行版本管理,但是存儲(chǔ)過(guò)程本身沒(méi)有版本控制,版本迭代更新的時(shí)候很麻煩。
- 它不適合高并發(fā)的場(chǎng)景。高并發(fā)的場(chǎng)景需要減少數(shù)據(jù)庫(kù)的壓力,有時(shí)數(shù)據(jù)庫(kù)會(huì)采用分庫(kù)分表的方式,而且對(duì)可擴(kuò)展性要求很高,在這種情況下,存儲(chǔ)過(guò)程會(huì)變得難以維護(hù),增加數(shù)據(jù)庫(kù)的壓力,顯然就不適用了。
三,存儲(chǔ)過(guò)程的創(chuàng)建與調(diào)用
- 存儲(chǔ)過(guò)程就是具有名字的一段代碼,用來(lái)完成一個(gè)特定的功能。
- 創(chuàng)建的存儲(chǔ)過(guò)程保存在數(shù)據(jù)庫(kù)的數(shù)據(jù)字典中。
3.1,存儲(chǔ)過(guò)程中的常用語(yǔ)法及參數(shù)
聲明語(yǔ)句結(jié)束符,可以自定義:
DELIMITER $$
聲明存儲(chǔ)過(guò)程:
CREATE PROCEDURE pro_name(IN num int)
存儲(chǔ)過(guò)程開(kāi)始和結(jié)束符號(hào):
BEGIN .... END
變量賦值:
SET num=1
變量定義:
DECLARE num int unsigned default 100;
創(chuàng)建mysql存儲(chǔ)過(guò)程、存儲(chǔ)函數(shù):
create procedure 存儲(chǔ)過(guò)程名(參數(shù))
存儲(chǔ)過(guò)程體:
create function 存儲(chǔ)函數(shù)名(參數(shù))
參數(shù)解析:
MySQL存儲(chǔ)過(guò)程的參數(shù)用在存儲(chǔ)過(guò)程的定義,共有三種參數(shù)類型,IN,OUT,INOUT,形式如:
CREATEPROCEDURE 存儲(chǔ)過(guò)程名([[IN |OUT |INOUT ] 參數(shù)名 數(shù)據(jù)類形...])
- IN 輸入?yún)?shù):表示調(diào)用者向過(guò)程傳入值(傳入值可以是字面量或變量)
- OUT 輸出參數(shù):表示過(guò)程向調(diào)用者傳出值(可以返回多個(gè)值)(傳出值只能是變量)
- INOUT 輸入輸出參數(shù):既表示調(diào)用者向過(guò)程傳入值,又表示過(guò)程向調(diào)用者傳出值(值只能是變量)
需要注意的是,這里的參數(shù)根據(jù)需求而定,如果不需要參數(shù),亦可不填寫!
3.2,存儲(chǔ)過(guò)程的使用
下面依次根據(jù)實(shí)例對(duì)不同的情況進(jìn)行演示:
首先準(zhǔn)備一張my_datas表:
mysql> create table if not exists `my_datas`( `id` int(20) not null auto_increment comment '數(shù)據(jù)id', `name` varchar(30) default null comment '姓名', `address` varchar(45) default null comment '地址', `time` datetime default null comment '創(chuàng)建時(shí)間', primary key(`id`) )engine=innodb auto_increment=1 default charset=utf8mb4; Query OK, 0 rows affected, 1 warning (0.33 sec)
查看結(jié)構(gòu)是否正確:
mysql> show columns from `my_datas`; +---------+-------------+------+-----+-------------------+-------------------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+-------------------+-------------------+ | id | int | NO | PRI | NULL | auto_increment | | name | varchar(30) | YES | | NULL | | | address | varchar(45) | YES | | NULL | | | time | datetime | YES | | NULL | DEFAULT_GENERATED | +---------+-------------+------+-----+-------------------+-------------------+ 4 rows in set (0.00 sec)
(1),創(chuàng)建存儲(chǔ)函數(shù),向數(shù)據(jù)表中插入50條數(shù)據(jù)
mysql> delimiter // #定義結(jié)束符 mysql> drop procedure if exists addMyData; -> create procedure addMyData() #創(chuàng)建一個(gè)存儲(chǔ)過(guò)程,名為:addMyData -> begin -> declare num int; -> set num =1; -> while num <=50 #插入50條數(shù)據(jù) -> do -> insert into `my_datas`(id,name,address,time) -> values(null,concat('數(shù)據(jù)_',num,'號(hào)'),concat('北京四 合院',round(rand()*10),'號(hào)'),concat(current_timestamp())); #concat函數(shù)拼接信息 -> set num =num +1; -> end -> while; -> end //; Query OK, 0 rows affected, 1 warning (0.03 sec) mysql> delimiter; #將語(yǔ)句的結(jié)束符號(hào)恢復(fù)為分號(hào)
默認(rèn)情況下,存儲(chǔ)過(guò)程和默認(rèn)數(shù)據(jù)庫(kù)相關(guān)聯(lián),如果想指定存儲(chǔ)過(guò)程創(chuàng)建在某個(gè)特定的數(shù)據(jù)庫(kù)下,那么在過(guò)程名前面加數(shù)據(jù)庫(kù)名做前綴。 在定義過(guò)程時(shí),使用 DELIMITER //命令將語(yǔ)句的結(jié)束符號(hào)從分號(hào) ; 臨時(shí)改為兩個(gè)//,使得過(guò)程體中使用的分號(hào)被直接傳遞到服務(wù)器,而不會(huì)被客戶端解釋。
調(diào)用存儲(chǔ)函數(shù),并查詢插入結(jié)果
mysql> call addMyData(); Query OK, 1 row affected (0.58 sec) mysql> select * from `my_datas`; +----+--------------+----------------------+---------------------+ | id | name | address | time | +----+--------------+----------------------+---------------------+ | 1 | 數(shù)據(jù)_1號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 2 | 數(shù)據(jù)_2號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 3 | 數(shù)據(jù)_3號(hào) | 北京四合院4號(hào) | 2022-08-24 14:21:17 | | 4 | 數(shù)據(jù)_4號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 5 | 數(shù)據(jù)_5號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 6 | 數(shù)據(jù)_6號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 7 | 數(shù)據(jù)_7號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 8 | 數(shù)據(jù)_8號(hào) | 北京四合院5號(hào) | 2022-08-24 14:21:17 | | 9 | 數(shù)據(jù)_9號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 10 | 數(shù)據(jù)_10號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 11 | 數(shù)據(jù)_11號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 12 | 數(shù)據(jù)_12號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 13 | 數(shù)據(jù)_13號(hào) | 北京四合院6號(hào) | 2022-08-24 14:21:17 | | 14 | 數(shù)據(jù)_14號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 15 | 數(shù)據(jù)_15號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 16 | 數(shù)據(jù)_16號(hào) | 北京四合院9號(hào) | 2022-08-24 14:21:17 | | 17 | 數(shù)據(jù)_17號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 18 | 數(shù)據(jù)_18號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 19 | 數(shù)據(jù)_19號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 20 | 數(shù)據(jù)_20號(hào) | 北京四合院9號(hào) | 2022-08-24 14:21:17 | | 21 | 數(shù)據(jù)_21號(hào) | 北京四合院2號(hào) | 2022-08-24 14:21:17 | | 22 | 數(shù)據(jù)_22號(hào) | 北京四合院2號(hào) | 2022-08-24 14:21:17 | | 23 | 數(shù)據(jù)_23號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 24 | 數(shù)據(jù)_24號(hào) | 北京四合院10號(hào) | 2022-08-24 14:21:17 | | 25 | 數(shù)據(jù)_25號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 26 | 數(shù)據(jù)_26號(hào) | 北京四合院5號(hào) | 2022-08-24 14:21:17 | | 27 | 數(shù)據(jù)_27號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 28 | 數(shù)據(jù)_28號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 29 | 數(shù)據(jù)_29號(hào) | 北京四合院10號(hào) | 2022-08-24 14:21:17 | | 30 | 數(shù)據(jù)_30號(hào) | 北京四合院10號(hào) | 2022-08-24 14:21:17 | | 31 | 數(shù)據(jù)_31號(hào) | 北京四合院0號(hào) | 2022-08-24 14:21:17 | | 32 | 數(shù)據(jù)_32號(hào) | 北京四合院2號(hào) | 2022-08-24 14:21:17 | | 33 | 數(shù)據(jù)_33號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 34 | 數(shù)據(jù)_34號(hào) | 北京四合院6號(hào) | 2022-08-24 14:21:17 | | 35 | 數(shù)據(jù)_35號(hào) | 北京四合院5號(hào) | 2022-08-24 14:21:17 | | 36 | 數(shù)據(jù)_36號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 37 | 數(shù)據(jù)_37號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 38 | 數(shù)據(jù)_38號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 39 | 數(shù)據(jù)_39號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 40 | 數(shù)據(jù)_40號(hào) | 北京四合院6號(hào) | 2022-08-24 14:21:17 | | 41 | 數(shù)據(jù)_41號(hào) | 北京四合院9號(hào) | 2022-08-24 14:21:17 | | 42 | 數(shù)據(jù)_42號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 43 | 數(shù)據(jù)_43號(hào) | 北京四合院9號(hào) | 2022-08-24 14:21:17 | | 44 | 數(shù)據(jù)_44號(hào) | 北京四合院5號(hào) | 2022-08-24 14:21:17 | | 45 | 數(shù)據(jù)_45號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 46 | 數(shù)據(jù)_46號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 47 | 數(shù)據(jù)_47號(hào) | 北京四合院1號(hào) | 2022-08-24 14:21:17 | | 48 | 數(shù)據(jù)_48號(hào) | 北京四合院7號(hào) | 2022-08-24 14:21:17 | | 49 | 數(shù)據(jù)_49號(hào) | 北京四合院10號(hào) | 2022-08-24 14:21:17 | | 50 | 數(shù)據(jù)_50號(hào) | 北京四合院9號(hào) | 2022-08-24 14:21:17 | +----+--------------+----------------------+---------------------+ 50 rows in set (0.00 sec)
這樣,50條需要的數(shù)據(jù)就能快速插入完畢。但是局限性在于插入的數(shù)據(jù)是在定義存儲(chǔ)過(guò)程中寫死的,不夠靈活。
(2),in輸入?yún)?shù)的使用
為了方便靈活的插入/修改/刪除/查詢我們需要的數(shù)據(jù),我們可以定義in 來(lái)輸入?yún)?shù),如下:
創(chuàng)建一個(gè)用域刪除指定id信息的存儲(chǔ)過(guò)程
mysql> delimiter !! mysql> create procedure delete_data(in ids int) #定義一個(gè)輸入的參數(shù) -> begin -> delete from `my_datas` where id=ids; -> end !! Query OK, 0 rows affected (0.05 sec) mysql> delimiter ;
執(zhí)行存儲(chǔ)過(guò)程并查看數(shù)據(jù)庫(kù)信息情況:
mysql> call delete_data(3); #輸入指定參數(shù) Query OK, 1 row affected (0.04 sec) mysql> select * from `my_datas` limit 3; +----+-------------+---------------------+---------------------+ | id | name | address | time | +----+-------------+---------------------+---------------------+ | 1 | 數(shù)據(jù)_1號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | | 2 | 數(shù)據(jù)_2號(hào) | 北京四合院8號(hào) | 2022-08-24 14:21:17 | | 4 | 數(shù)據(jù)_4號(hào) | 北京四合院3號(hào) | 2022-08-24 14:21:17 | +----+-------------+---------------------+---------------------+ 3 rows in set (0.00 sec)
在存儲(chǔ)過(guò)程中設(shè)置了需要傳參的變量ids,調(diào)用存儲(chǔ)過(guò)程的時(shí)候,通過(guò)傳參將3賦值給ids,然后進(jìn)行存儲(chǔ)過(guò)程里的SQL操作。
(3),out參數(shù)的使用
構(gòu)建一個(gè)簡(jiǎn)單的存儲(chǔ)過(guò)程:
mysql> create procedure sums(a int ,b int ,out c int) -> begin -> set c = a+b; -> end // Query OK, 0 rows affected (0.03 sec) mysql> delimiter ;
進(jìn)行驗(yàn)證:
mysql> call sums(11,25,@s); Query OK, 0 rows affected (0.01 sec) mysql> select @s; #正常輸出c的值 +------+ | @s | +------+ | 36 | +------+
(4),inout參數(shù)的使用
構(gòu)建一個(gè)inout型的存儲(chǔ)過(guò)程:
mysql> delimiter // mysql> create procedure inout_test(inout test int) -> begin -> select test; -> set test=100; -> select test; -> end -> // Query OK, 0 rows affected (0.07 sec) mysql> delimiter ;
測(cè)試執(zhí)行過(guò)程:
mysql> set @test=52 -> ; Query OK, 0 rows affected (0.00 sec) mysql> call inout_test(@test); +------+ | test | +------+ | 52 | +------+ 1 row in set (0.00 sec) +------+ | test | +------+ | 100 | +------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) #調(diào)用了inout_param存儲(chǔ)過(guò)程,接受了輸入的參數(shù),也輸出參數(shù),改變了變量 mysql> select @test; +-------+ | @test | +-------+ | 100 | +-------+ 1 row in set (0.00 sec)
注意事項(xiàng):參數(shù)的名字不要和列名相同,不然在過(guò)程體中,參數(shù)名會(huì)當(dāng)作列名來(lái)處理,并且,存儲(chǔ)過(guò)程命名盡量不要跟一些常用函數(shù)命名一樣,否則sql檢查會(huì)出錯(cuò)。
四,存儲(chǔ)過(guò)程中的變量及使用細(xì)則
4.1,變量定義
局部變量聲明一定要放在存儲(chǔ)過(guò)程體的開(kāi)始:
DECLARE 變量名 數(shù)據(jù)類型(int,float,date……)
例如:
DECLARE numbers int
DECLARE l_datetime datetime DEFAULT '2022-09-31 16:12:35';
DECLARE l_varchar varchar(255) DEFAULT '黎治躍在內(nèi)卷!';
4.2,變量賦值
SET 變量名 = 表達(dá)式值 [,variable_name = expression ...]
4.3,用戶變量的使用
mysql > SELECT '黎治躍在內(nèi)卷' into @l; Query OK, 0 rows affected (0.00 sec) mysql > SELECT @l; +-------------+ | @l | +-------------+ | 黎治躍在內(nèi)卷 | +-------------+ 1 row in set (0.00 sec) mysql> set @z='做個(gè)人吧,黎治躍'; Query OK, 0 rows affected (0.00 sec) mysql> select @z; +--------------------------+ | @z | +--------------------------+ | 做個(gè)人吧,黎治躍 | +--------------------------+ 1 row in set (0.00 sec) mysql> SET @y=5+2+52; Query OK, 0 rows affected (0.00 sec) mysql> select @y; +------+ | @y | +------+ | 59 | +------+ 1 row in set (0.00 sec)
存儲(chǔ)過(guò)程中使用用戶變量:
mysql> create procedure see() select concat(@lzy,'Java全能選手'); Query OK, 0 rows affected (0.02 sec) mysql> set @lzy ='黎治躍:'; Query OK, 0 rows affected (0.00 sec) mysql> call see(); +---------------------------------+ | concat(@lzy,'Java全能選手') | +---------------------------------+ | 黎治躍:Java全能選手 | +---------------------------------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
在存儲(chǔ)過(guò)程間傳遞全局范圍的用戶變量:
mysql> CREATE PROCEDURE p1() SET @last_procedure='l1'; Query OK, 0 rows affected (0.02 sec) mysql> CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_procedure); Query OK, 0 rows affected (0.03 sec) mysql> CALL p1( ); mysql> CALL p2( ); +-----------------------------------------------+ | CONCAT('Last procedure was ',@last_proc | +-----------------------------------------------+ | Last procedure was l1 | +-----------------------------------------------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)
注意:
1、用戶變量名一般以@開(kāi)頭
2、濫用用戶變量會(huì)導(dǎo)致程序難以理解及管理
4.4,存儲(chǔ)過(guò)程的一些常用查看命令
查看具體存儲(chǔ)過(guò)程信息
show create procedure 存儲(chǔ)過(guò)程名 \G
查看所有存儲(chǔ)過(guò)程
show procedure status \G
模糊查詢對(duì)應(yīng)的存儲(chǔ)過(guò)程信息
show procedure status like “模糊查詢名” \G
查看指定表中的存儲(chǔ)信息
select * from 表名 where routine_name = '存儲(chǔ)過(guò)程名' \G
五,常用的存儲(chǔ)過(guò)程的控制語(yǔ)句
5.1,條件語(yǔ)句
5.1.1,if-then-else
mysql > delimiter // mysql > create prcedure test2(in s int) -> begin -> declare num int; -> set num=s+1; -> if num=0 then -> insert into `new_table` values(555); -> end if; -> if s=0 then -> update `new_table` set s1=s1+1; -> else -> update `new_table` set s1=s1+2; -> end if; -> end; -> // Query OK, 0 rows affected (0.07 sec) mysql > delimiter ;
5.1.2,case語(yǔ)句
mysql > delimiter // mysql > create procedure test(in sb int) -> begin -> declare num int; -> set num=sb+1; -> case num -> when 0 then -> insert into `new_table` values(23); -> when 1 then -> insert into `new_table` values(24); -> else -> insert into `new_table` values(25); -> end case; -> end; -> // Query OK, 0 rows affected (0.06 sec) mysql > delimiter ;
5.2,循環(huán)語(yǔ)句
5.2.1,while ……end while語(yǔ)句
mysql > delimiter // mysql > create procedure test() -> begin -> declare num int; -> set num=0; -> while num<6 do -> insert into `new_tables` values(num); -> set num=num+1; -> end while; -> end; -> // Query OK, 0 rows affected (0.03 sec) mysql > delimiter ;
5.2.2,repeat……end repeat語(yǔ)句
這個(gè)語(yǔ)句與while語(yǔ)句的不同之處在于while是先檢查再執(zhí)行,而repeat語(yǔ)句是執(zhí)行操作后檢查結(jié)果。
mysql > delimiter // mysql > create procedure test() -> begin -> declare num int; -> set num=0; -> repeat -> insert into `new_table` values(num); -> set num=num+1; -> until num>=5 #循環(huán)條件 -> end repeat; -> end; -> // Query OK, 0 rows affected (0.04 sec) mysql > delimiter ;
5.2.3,loop……end loop語(yǔ)句
loop循環(huán)相當(dāng)于一個(gè)while True ...if ... break 循環(huán),與repeat一循環(huán)不同,loop可以在循環(huán)體的任何位置通過(guò)leave離開(kāi)循環(huán),而repeat只能在循環(huán)體最后進(jìn)行until判斷 。此外loop還提供了循環(huán)標(biāo)簽,用于在嵌套·循環(huán)中標(biāo)識(shí)不同層次的循環(huán)。
mysql > delimiter // mysql > create procedure test5() -> begin -> declare num int; -> set num=0; -> LOOP1:loop -> insert into `new_table` values(num); -> set num=num+1; -> if num >=5 then -> leave LOOP1; -> end if; -> end loop; -> end; -> // Query OK, 0 rows affected (0.04 sec) mysql > delimiter ;
六,其他相關(guān)知識(shí)點(diǎn)
6.1,存儲(chǔ)過(guò)程體
存儲(chǔ)過(guò)程體包含了在過(guò)程調(diào)用時(shí)必須執(zhí)行的語(yǔ)句,例如:dml、ddl語(yǔ)句,if-then-else和while-do語(yǔ)句、聲明變量的declare語(yǔ)句等
過(guò)程體格式:以begin開(kāi)始,以end結(jié)束(可嵌套)
BEGIN
BEGIN
BEGIN
statements;
END
END
END
每個(gè)嵌套塊及其中的每條語(yǔ)句,必須以分號(hào)結(jié)束,表示過(guò)程體結(jié)束的begin-end塊(又叫做復(fù)合語(yǔ)句compound statement),則不需要分號(hào)。
為語(yǔ)句塊貼標(biāo)簽:
label1: BEGIN
label2: BEGIN
label3: BEGIN
statements;
END label3 ;
END label2;
END label1
標(biāo)簽有兩個(gè)作用:
1、增強(qiáng)代碼的可讀性
2、在某些語(yǔ)句(例如:leave和iterate語(yǔ)句),需要用到標(biāo)簽
6.2,MySQL AlTER命令對(duì)表的靈活操作
6.2.1,刪除,添加表字段及默認(rèn)值
刪除表字段
ALTER TABLE 表名 DROP 字段名;添加表字段
ALTER TABLE 表名 ADD 字段名 字段數(shù)據(jù)類型;添加表字段默認(rèn)值
ALTER TABLE 表名 ALTER 字段名 SET DEFAULT 默認(rèn)值;刪除表字段默認(rèn)值
ALTER TABLE 表名 ALTER 字段名 DROP DEFAULT;
另外,如果需要將表字段插入指定的位置,可以使用MySQL提供的關(guān)鍵字 FIRST (設(shè)定位第一列), AFTER 字段名(設(shè)定位于某個(gè)字段之后)。使用show columns查看表結(jié)構(gòu)變化:
mysql> show columns from user; +----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | username | varchar(30) | YES | | NULL | | | address | varchar(45) | YES | | NULL | | +----------+-------------+------+-----+---------+----------------+ 3 rows in set (0.04 sec) mysql> alter table user add time datetime; #添加一個(gè)time字段 Query OK, 0 rows affected (0.17 sec) Records: 0 Duplicates: 0 Warnings: 0 #在address后面添加一個(gè)sex字段 mysql> alter table user add sex tinyint(1) after address;Query OK, 0 rows affected, 1 warning (0.41 sec) Records: 0 Duplicates: 0 Warnings: 1 mysql> show columns from user; +----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | username | varchar(30) | YES | | NULL | | | address | varchar(45) | YES | | NULL | | | sex | tinyint(1) | YES | | NULL | | | time | datetime | YES | | NULL | | +----------+-------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec)
6.2.2,CHANGE與MODIFY對(duì)修改字段的作用
當(dāng)需要修改字段類型或者字段名時(shí),常常會(huì)使用到change與modify關(guān)鍵字
modify使用
alter table 表名 modify 字段名 字段屬性(更改后)
modify主要用于更改數(shù)據(jù)字段范圍,當(dāng)遇到在數(shù)據(jù)庫(kù)構(gòu)建時(shí),范圍數(shù)據(jù)定義過(guò)小,或者范圍數(shù)據(jù)定義過(guò)大浪費(fèi)內(nèi)存空間時(shí),對(duì)字段屬性的更改。
change使用
alter table 表名 change old字段名 new字段名 對(duì)應(yīng)的字段屬性
change關(guān)鍵字主要用于對(duì)字段名的更改,在語(yǔ)法上CHANGE 關(guān)鍵字之后,緊跟著的是你要修改的字段名,然后指定新字段名及類型。但是CHANGE又不僅僅可以更改字段名,它也可以同時(shí)修改指明后的字段屬性,同時(shí)對(duì)字段名和字段屬性進(jìn)行修改。
#使用change僅修改字段名 mysql> alter table user change address address varchar(40); Query OK, 499 rows affected (0.38 sec) Records: 499 Duplicates: 0 Warnings: 0 #使用modify僅修改字段屬性 mysql> alter table user modify address varchar(45); Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0 #使用change同時(shí)修改字段名和字段屬性 mysql> alter table user change address u_address varchar(40)); Query OK, 499 rows affected (0.26 sec) Records: 499 Duplicates: 0 Warnings: 0 #查看更改后的表結(jié)構(gòu) mysql> show columns from user; +-----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | username | varchar(30) | YES | | NULL | | | u_address | varchar(40) | YES | | NULL | | | sex | tinyint(1) | YES | | NULL | | | time | datetime | YES | | NULL | | +-----------+-------------+------+-----+---------+----------------+ 5 rows in set (0.01 sec)
6.2.3,其他修改的使用
修改指定表的數(shù)據(jù)引擎
alter table user engine=指定數(shù)據(jù)引擎
例如:ALTER TABLE testalter_tbl ENGINE = MYISAM;
如果對(duì)當(dāng)前數(shù)據(jù)表信息不清楚的話可以通過(guò)SHOW TABLE STATUS命令進(jìn)行查看。
例如:查看當(dāng)前user表的信息
mysql> show table status like 'user' \G; *************************** 1. row *************************** Name: user Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 499 Avg_row_length: 131 Data_length: 65536 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: 500 Create_time: 2022-08-24 17:32:27 Update_time: NULL Check_time: NULL Collation: utf8mb4_0900_ai_ci Checksum: NULL Create_options: Comment: 1 row in set (0.03 sec) ERROR: No query specified
修改表名
alter table old表名 rename to new表名
此外,ALTER關(guān)鍵字的操作也不僅僅局限于操作表,在以后的索引,外鍵上也有很多作用。
總結(jié)
到此這篇關(guān)于MySQL存儲(chǔ)過(guò)程的創(chuàng)建使用以及實(shí)現(xiàn)數(shù)據(jù)快速插入的文章就介紹到這了,更多相關(guān)MySQL存儲(chǔ)過(guò)程快速插入數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 通過(guò)存儲(chǔ)過(guò)程動(dòng)態(tài)創(chuàng)建MySQL對(duì)象的流程步驟
- 利用Mysql定時(shí)+存儲(chǔ)過(guò)程創(chuàng)建臨時(shí)表統(tǒng)計(jì)數(shù)據(jù)的過(guò)程
- 詳解MySQL中存儲(chǔ)函數(shù)創(chuàng)建與觸發(fā)器設(shè)置
- MySQL一次性創(chuàng)建表格存儲(chǔ)過(guò)程實(shí)戰(zhàn)
- 詳解MySQL存儲(chǔ)過(guò)程的創(chuàng)建和調(diào)用
- mysql創(chuàng)建存儲(chǔ)的全過(guò)程
相關(guān)文章
Centos7.3下mysql5.7.18安裝并修改初始密碼的方法
這篇文章主要為大家詳細(xì)介紹了Centos7.3下mysql5.7.18安裝并修改初始密碼的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06使用Shell腳本進(jìn)行MySql權(quán)限修改的實(shí)現(xiàn)教程
原先數(shù)據(jù)配置文件中有bind-address=127.0.0.1,注釋掉此配置后,原數(shù)據(jù)庫(kù)中默認(rèn)帶%root的權(quán)限,現(xiàn)在需要通過(guò)腳本實(shí)現(xiàn)白名單列表中的ip添加權(quán)限允許訪問(wèn)數(shù)據(jù)庫(kù),本文給大家介紹了使用Shell腳本進(jìn)行MySql權(quán)限修改的實(shí)現(xiàn)教程,需要的朋友可以參考下2024-03-03Mysql數(shù)據(jù)庫(kù)索引面試題(程序員基礎(chǔ)技能)
索引是Mysql的一塊硬骨頭,但是對(duì)于程序猿來(lái)說(shuō)又是十分重要的基礎(chǔ)技能。本文將從索引原理、索引設(shè)計(jì)原則方面闡述Mysql索引,相信通過(guò)本文的學(xué)習(xí)你將完美征服阿里面試官2021-05-05MySQL數(shù)據(jù)庫(kù)常用命令小結(jié)
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)命令,主要包括對(duì)數(shù)據(jù)庫(kù)常用命令及數(shù)據(jù)庫(kù)中對(duì)表的命令,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01一文詳解如何在MySQL中處理JSON數(shù)據(jù)
在當(dāng)今的大數(shù)據(jù)時(shí)代,JSON作為一種輕量級(jí)的數(shù)據(jù)交換格式,被廣泛應(yīng)用于Web應(yīng)用的數(shù)據(jù)傳輸,隨著MySQL 5.7的發(fā)布,MySQL引入了對(duì)JSON數(shù)據(jù)類型的支持,本文將詳細(xì)介紹如何在MySQL中處理JSON數(shù)據(jù),并提供示例,需要的朋友可以參考下2024-08-08mysql使用報(bào)錯(cuò)1142(42000)的問(wèn)題及解決
這篇文章主要介紹了mysql使用報(bào)錯(cuò)1142(42000)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08mysql之過(guò)濾分組的具體實(shí)現(xiàn)
在MySQL中過(guò)濾分組數(shù)據(jù)通常使用GROUP BY結(jié)合HAVING子句和WHERE子句,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Centos7 移動(dòng)mysql5.7.19 數(shù)據(jù)存儲(chǔ)位置的操作方法
這篇文章主要介紹了Centos7 移動(dòng)mysql5.7.19 數(shù)據(jù)存儲(chǔ)位置的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-10-10