<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
自MySQL 5.0 版本開始支援儲存過程。儲存過程(Stored Procedure)是一種在資料庫中儲存複雜程式,以便外部程式呼叫的一種資料庫物件。
儲存過程是為了完成特定功能的SQL語句集,經編譯建立並儲存在資料庫中,使用者可通過指定儲存過程的名字並給定引數(需要時)來呼叫執行。
儲存過程思想就是資料庫 SQL 語言層面的程式碼封裝與重用。類似於Java開發中封裝工具類方便以後直接呼叫的作用。
優點
缺點
宣告語句結束符,可以自定義:
DELIMITER $$
宣告儲存過程:
CREATE PROCEDURE pro_name(IN num int)
儲存過程開始和結束符號:
BEGIN .... END
變數賦值:
SET num=1
變數定義:
DECLARE num int unsigned default 100;
建立mysql儲存過程、儲存函數:
create procedure 儲存過程名(引數)
儲存過程體:
create function 儲存函數名(引數)
引數解析:
MySQL儲存過程的引數用在儲存過程的定義,共有三種引數型別,IN,OUT,INOUT,形式如:
CREATEPROCEDURE 儲存過程名([[IN |OUT |INOUT ] 引數名 資料類形...])
需要注意的是,這裡的引數根據需求而定,如果不需要引數,亦可不填寫!
下面依次根據範例對不同的情況進行演示:
首先準備一張my_datas表:
mysql> create table if not exists `my_datas`( `id` int(20) not null auto_increment comment '資料id', `name` varchar(30) default null comment '姓名', `address` varchar(45) default null comment '地址', `time` datetime default null comment '建立時間', primary key(`id`) )engine=innodb auto_increment=1 default charset=utf8mb4; Query OK, 0 rows affected, 1 warning (0.33 sec)
檢視結構是否正確:
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),建立儲存函數,向資料表中插入50條資料
mysql> delimiter // #定義結束符 mysql> drop procedure if exists addMyData; -> create procedure addMyData() #建立一個儲存過程,名為:addMyData -> begin -> declare num int; -> set num =1; -> while num <=50 #插入50條資料 -> do -> insert into `my_datas`(id,name,address,time) -> values(null,concat('資料_',num,'號'),concat('北京四 合院',round(rand()*10),'號'),concat(current_timestamp())); #concat函數拼接資訊 -> set num =num +1; -> end -> while; -> end //; Query OK, 0 rows affected, 1 warning (0.03 sec) mysql> delimiter; #將語句的結束符號恢復為分號
預設情況下,儲存過程和預設資料庫相關聯,如果想指定儲存過程建立在某個特定的資料庫下,那麼在過程名前面加資料庫名做字首。 在定義過程時,使用 DELIMITER //命令將語句的結束符號從分號 ; 臨時改為兩個//,使得過程體中使用的分號被直接傳遞到伺服器,而不會被使用者端解釋。
呼叫儲存函數,並查詢插入結果
mysql> call addMyData(); Query OK, 1 row affected (0.58 sec) mysql> select * from `my_datas`; +----+--------------+----------------------+---------------------+ | id | name | address | time | +----+--------------+----------------------+---------------------+ | 1 | 資料_1號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 2 | 資料_2號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 3 | 資料_3號 | 北京四合院4號 | 2022-08-24 14:21:17 | | 4 | 資料_4號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 5 | 資料_5號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 6 | 資料_6號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 7 | 資料_7號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 8 | 資料_8號 | 北京四合院5號 | 2022-08-24 14:21:17 | | 9 | 資料_9號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 10 | 資料_10號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 11 | 資料_11號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 12 | 資料_12號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 13 | 資料_13號 | 北京四合院6號 | 2022-08-24 14:21:17 | | 14 | 資料_14號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 15 | 資料_15號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 16 | 資料_16號 | 北京四合院9號 | 2022-08-24 14:21:17 | | 17 | 資料_17號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 18 | 資料_18號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 19 | 資料_19號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 20 | 資料_20號 | 北京四合院9號 | 2022-08-24 14:21:17 | | 21 | 資料_21號 | 北京四合院2號 | 2022-08-24 14:21:17 | | 22 | 資料_22號 | 北京四合院2號 | 2022-08-24 14:21:17 | | 23 | 資料_23號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 24 | 資料_24號 | 北京四合院10號 | 2022-08-24 14:21:17 | | 25 | 資料_25號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 26 | 資料_26號 | 北京四合院5號 | 2022-08-24 14:21:17 | | 27 | 資料_27號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 28 | 資料_28號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 29 | 資料_29號 | 北京四合院10號 | 2022-08-24 14:21:17 | | 30 | 資料_30號 | 北京四合院10號 | 2022-08-24 14:21:17 | | 31 | 資料_31號 | 北京四合院0號 | 2022-08-24 14:21:17 | | 32 | 資料_32號 | 北京四合院2號 | 2022-08-24 14:21:17 | | 33 | 資料_33號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 34 | 資料_34號 | 北京四合院6號 | 2022-08-24 14:21:17 | | 35 | 資料_35號 | 北京四合院5號 | 2022-08-24 14:21:17 | | 36 | 資料_36號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 37 | 資料_37號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 38 | 資料_38號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 39 | 資料_39號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 40 | 資料_40號 | 北京四合院6號 | 2022-08-24 14:21:17 | | 41 | 資料_41號 | 北京四合院9號 | 2022-08-24 14:21:17 | | 42 | 資料_42號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 43 | 資料_43號 | 北京四合院9號 | 2022-08-24 14:21:17 | | 44 | 資料_44號 | 北京四合院5號 | 2022-08-24 14:21:17 | | 45 | 資料_45號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 46 | 資料_46號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 47 | 資料_47號 | 北京四合院1號 | 2022-08-24 14:21:17 | | 48 | 資料_48號 | 北京四合院7號 | 2022-08-24 14:21:17 | | 49 | 資料_49號 | 北京四合院10號 | 2022-08-24 14:21:17 | | 50 | 資料_50號 | 北京四合院9號 | 2022-08-24 14:21:17 | +----+--------------+----------------------+---------------------+ 50 rows in set (0.00 sec)
這樣,50條需要的資料就能快速插入完畢。但是侷限性在於插入的資料是在定義儲存過程中寫死的,不夠靈活。
(2),in輸入引數的使用
為了方便靈活的插入/修改/刪除/查詢我們需要的資料,我們可以定義in 來輸入引數,如下:
建立一個用域刪除指定id資訊的儲存過程
mysql> delimiter !! mysql> create procedure delete_data(in ids int) #定義一個輸入的引數 -> begin -> delete from `my_datas` where id=ids; -> end !! Query OK, 0 rows affected (0.05 sec) mysql> delimiter ;
執行儲存過程並檢視資料庫資訊情況:
mysql> call delete_data(3); #輸入指定引數 Query OK, 1 row affected (0.04 sec) mysql> select * from `my_datas` limit 3; +----+-------------+---------------------+---------------------+ | id | name | address | time | +----+-------------+---------------------+---------------------+ | 1 | 資料_1號 | 北京四合院3號 | 2022-08-24 14:21:17 | | 2 | 資料_2號 | 北京四合院8號 | 2022-08-24 14:21:17 | | 4 | 資料_4號 | 北京四合院3號 | 2022-08-24 14:21:17 | +----+-------------+---------------------+---------------------+ 3 rows in set (0.00 sec)
在儲存過程中設定了需要傳參的變數ids,呼叫儲存過程的時候,通過傳參將3賦值給ids,然後進行儲存過程裡的SQL操作。
(3),out引數的使用
構建一個簡單的儲存過程:
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 ;
進行驗證:
mysql> call sums(11,25,@s); Query OK, 0 rows affected (0.01 sec) mysql> select @s; #正常輸出c的值 +------+ | @s | +------+ | 36 | +------+
(4),inout引數的使用
構建一個inout型的儲存過程:
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 ;
測試執行過程:
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) #呼叫了inout_param儲存過程,接受了輸入的引數,也輸出引數,改變了變數 mysql> select @test; +-------+ | @test | +-------+ | 100 | +-------+ 1 row in set (0.00 sec)
注意事項:引數的名字不要和列名相同,不然在過程體中,引數名會當作列名來處理,並且,儲存過程命名儘量不要跟一些常用函數命名一樣,否則sql檢查會出錯。
區域性變數宣告一定要放在儲存過程體的開始:
DECLARE 變數名 資料型別(int,float,date……)
例如:
DECLARE numbers int
DECLARE l_datetime datetime DEFAULT '2022-09-31 16:12:35';
DECLARE l_varchar varchar(255) DEFAULT '黎治躍在內卷!';
SET 變數名 = 表示式值 [,variable_name = expression ...]
mysql > SELECT '黎治躍在內卷' into @l; Query OK, 0 rows affected (0.00 sec) mysql > SELECT @l; +-------------+ | @l | +-------------+ | 黎治躍在內卷 | +-------------+ 1 row in set (0.00 sec) mysql> set @z='做個人吧,黎治躍'; Query OK, 0 rows affected (0.00 sec) mysql> select @z; +--------------------------+ | @z | +--------------------------+ | 做個人吧,黎治躍 | +--------------------------+ 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)
儲存過程中使用使用者變數:
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)
在儲存過程間傳遞全域性範圍的使用者變數:
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、使用者變數名一般以@開頭
2、濫用使用者變數會導致程式難以理解及管理
檢視具體儲存過程資訊
show create procedure 儲存過程名 G
檢視所有儲存過程
show procedure status G
模糊查詢對應的儲存過程資訊
show procedure status like “模糊查詢名” G
檢視指定表中的儲存資訊
select * from 表名 where routine_name = '儲存過程名' G
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 ;
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 ;
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 ;
這個語句與while語句的不同之處在於while是先檢查再執行,而repeat語句是執行操作後檢查結果。
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 #迴圈條件 -> end repeat; -> end; -> // Query OK, 0 rows affected (0.04 sec) mysql > delimiter ;
loop迴圈相當於一個while True ...if ... break 迴圈,與repeat一回圈不同,loop可以在迴圈體的任何位置通過leave離開回圈,而repeat只能在迴圈體最後進行until判斷 。此外loop還提供了迴圈標籤,用於在巢狀·迴圈中標識不同層次的迴圈。
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 ;
儲存過程體包含了在過程呼叫時必須執行的語句,例如:dml、ddl語句,if-then-else和while-do語句、宣告變數的declare語句等
過程體格式:以begin開始,以end結束(可巢狀)
BEGIN
BEGIN
BEGIN
statements;
END
END
END
每個巢狀塊及其中的每條語句,必須以分號結束,表示過程體結束的begin-end塊(又叫做複合語句compound statement),則不需要分號。
為語句塊貼標籤:
label1: BEGIN
label2: BEGIN
label3: BEGIN
statements;
END label3 ;
END label2;
END label1
標籤有兩個作用:
1、增強程式碼的可讀性
2、在某些語句(例如:leave和iterate語句),需要用到標籤
刪除表欄位
ALTER TABLE 表名 DROP 欄位名;新增表欄位
ALTER TABLE 表名 ADD 欄位名 欄位資料型別;新增表欄位預設值
ALTER TABLE 表名 ALTER 欄位名 SET DEFAULT 預設值;刪除表欄位預設值
ALTER TABLE 表名 ALTER 欄位名 DROP DEFAULT;
另外,如果需要將表欄位插入指定的位置,可以使用MySQL提供的關鍵字 FIRST (設定位第一列), AFTER 欄位名(設定位於某個欄位之後)。使用show columns檢視表結構變化:
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; #新增一個time欄位 Query OK, 0 rows affected (0.17 sec) Records: 0 Duplicates: 0 Warnings: 0 #在address後面新增一個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)
當需要修改欄位型別或者欄位名時,常常會使用到change與modify關鍵字
modify使用
alter table 表名 modify 欄位名 欄位屬性(更改後)
modify主要用於更改資料欄位範圍,當遇到在資料庫構建時,範圍資料定義過小,或者範圍資料定義過大浪費記憶體空間時,對欄位屬性的更改。
change使用
alter table 表名 change old欄位名 new欄位名 對應的欄位屬性
change關鍵字主要用於對欄位名的更改,在語法上CHANGE 關鍵字之後,緊跟著的是你要修改的欄位名,然後指定新欄位名及型別。但是CHANGE又不僅僅可以更改欄位名,它也可以同時修改指明後的欄位屬性,同時對欄位名和欄位屬性進行修改。
#使用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同時修改欄位名和欄位屬性 mysql> alter table user change address u_address varchar(40)); Query OK, 499 rows affected (0.26 sec) Records: 499 Duplicates: 0 Warnings: 0 #檢視更改後的表結構 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)
修改指定表的資料引擎
alter table user engine=指定資料引擎
例如:ALTER TABLE testalter_tbl ENGINE = MYISAM;
如果對當前資料表資訊不清楚的話可以通過SHOW TABLE STATUS命令進行檢視。
例如:檢視當前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關鍵字的操作也不僅僅侷限於操作表,在以後的索引,外來鍵上也有很多作用。
到此這篇關於MySQL儲存過程的建立使用以及實現資料快速插入的文章就介紹到這了,更多相關MySQL儲存過程快速插入資料內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45