mysql資料庫存儲過程教程
存儲過程(stored
procere)是一組為了完成特定功能的sql語句集,經編譯後存儲在資料庫中,用戶通過指定存儲過程的名字並給定參數(如果該存儲過程帶有參數)來調用執行它。
一個存儲過程是一個可編程的函數,它在資料庫中創建並保存。
❷ 用idea在mysql資料庫中怎樣創建存儲過程
直接在控制台idea
的資料庫控制台
寫創建存儲過程的語句
-執行即可
執行語句後
圖中文件中就可以看到
❸ mysql存儲過程及流程式控制制
存儲過程(Stored
Procere)是一組為了完成特定功能的SQL語句集功能是將常用或復雜的工作,預先用SQL語句寫好並用一個指定名稱存儲起來,
以後需要資料庫提供與已定義好的存儲過程的功能相同的服務時,只需調用
call
存儲過程名字,
即可自動完成命令。存儲過程是由流控制和SQL語句書寫的過程,這個過程經編譯和優化後存儲在資料庫伺服器中,可由應用程序通過一個調用來執行,而且允許用戶聲明變數
。同時,存儲過程可以接收和輸出參數、返回執行存儲過程的狀態值,也可以嵌套調用。
❹ mysql 存儲過程 DDL 參數
MySQL8.0 開始支持原⼦ DDL(atomic DDL),數據字典的更新,存儲引擎操作,寫⼆進制日誌結合成了一個事務。在沒有原⼦DDL之前,DROP TABLE test1,test2;如遇到server crash,可能會有test1被drop了,test2沒有被drop掉。下面來看下在MySQL8.0之前和MySQL8.0 數據字典的區別
在MySQL8.0 之前,Data Dictionary除了存在與.FRM, .TRG, .OPT ⽂件外,還存在於系統表中(MyISAM ⾮事務引擎表中),在MySQL8.0 ,Data Dictionary 全部存在於Data Dictionary Storage Engine(即 InnoDB表中),這使crash recovery 維持原⼦性成為了可能
存儲引擎⽀持
目前,只有InnoDB存儲引擎⽀持原子DDL,為了實現原子DDL,Innodb要寫DDL logs 到 mysql.innodb_ddl_log 表,這是⼀個隱藏在mysql.ibd 數據字典表空間⾥的數據字典表。要看mysql.innodb_ddl_log 中的內容,需要
SET GLOBALLOG_ERROR_VERBOSITY=3;(MySQL 8.0 默認為2,error log 記錄Errors and
warnings,不不記錄notes)
SET GLOBAL innodb_print_ddl_logs=1;
CREATE TABLEt1 (c1 INT)ENGINE=InnoDB;
查看error log
[Note] [MY-011066] InnoDB: DDL loginsert: [DDLrecord:DELETE SPACE,id=30,
thread_id=25, space_id=9, old_file_path=./test/t1.ibd]
[Note] [MY-011066]InnoDB:DDL logdelete:by id30
[Note] [MY-011066]InnoDB:DDL loginsert: [DDLrecord: REMOVECACHE,id=31,
thread_id=25, table_id=1066, new_file_path=test/t1]
[Note] [MY-011066]InnoDB:DDL logdelete:by id31
[Note] [MY-011066]InnoDB:DDL loginsert: [DDLrecord: FREE,id=32, thread_
id=25, space_id=9, index_id=143, page_no=4]
[Note] [MY-011066]InnoDB:DDL log delete:by id32
[Note] [MY-011066]InnoDB:DDL logpost ddl :begin for thread id: 25
[Note] [MY-011066]InnoDB:DDL logpost ddl :end for thread id: 25
原子DDL 操作步驟
准備:創建所需的對象並將DDL⽇志寫入 mysql.innodb_ddl_log表中。DDL日誌定義了如何前滾和回滾DDL操作。
執行:執⾏DDL操作。例如,為CREATE TABLE操作執⾏創建。
提交:更新數據字典並提交數據字典事務。
Post-DDL:重播並從mysql.innodb_ddl_log表格中刪除DDL⽇志。為確保回滾可以安全執⾏⽽不引⼊不⼀致性,在此最後階段執⾏⽂件操作(如重命名或刪除數據文件)。這一階段還從 mysql.innodb_dynamic_metadata的數據字典表刪除的動態元數據為了DROP TABLE,TRUNCATE和其它重建表的DDL操作。
⽆論事務是提交還是回滾,DDL日誌都會mysql.innodb_ddl_log在Post-DDL階段重播並從表中刪除 。mysql.innodb_ddl_log如果伺服器在DDL操作期間暫停,DDL⽇志應該只保留在表中。在這種情況下,DDL⽇志會在恢復後重播並刪除。
在恢復情況下,當伺服器重新啟動時,可能會提交或回退DDL事務。如果在重做⽇志和⼆進制日誌中存在DDL操作的提交階段期間執⾏的數據字典事務,則該操作被認為是成功的並且被前滾。否則,在InnoDB重放數據字典重做日誌時回滾不完整的數據字典事務 ,並且回滾DDL事務。
原⼦DDL ⽀持類型
• DROP TABLES , all tables dropped or none
• DROP SCHEMA, all entities in the schema are dropped, or none
• Note that atomic DDL statements will be rolled back or committed even in case of crash, e.g. RENAME TABLES
• CREATE TABLE would be successfully committed or rolled back (no orphan ibd left)
• TRUNCATE TABLE (including InnoDB tables with FTS AUX tables) would be successfully committed or rolled back
• RENAME TABLES, all or none
• ALTER TABLE successful or not done
示例
結論
在MySQL8.0之前,alter table 操作在server crash的情況下,會遺留.frm,.ibd文件。MySQL8.0 能實現原⼦DDL(包括 DROP TABLE, DROP SCHEMA, CREATE TABLE, TRUNCATE TABLE, ALTER TABLE),alter table 操作,在server crash的情況下,不會遺留.frm,.ibd臨時文件。讓我們⼀起期待MySQL8.0 GA的到來吧!
❺ mysql中的存儲過程、觸發器、視圖的用法
建立存儲過程
Create procere、Create function
下面是它們的格式:
Create proceresp_Name ([proc_parameter ])
routine_body
這里的參數類型可以是 IN OUT INOUTT ,意思和單詞的意思是一樣的,IN 表示是傳進來的參數,
OUT 是表示傳出去的參數,INOUT 是表示傳進來但最終傳回的參數。
Create functionsp_Name ([func_parameter ])
Returns type
Routine_body
Returns type 指定了返回的類型,這里給定的類型與返回值的類型要是一樣的,否則會報錯。
下面給出兩個簡單的例子來說明:
1、 顯示 Mysql 當前版本
執行結果
mysql> use welefen;
Database changed
mysql> delimiter // #定義//作為結束標記符號
mysql> create procere getversion(out param1 varchar(50)) #param1為傳出參數
-> begin
-> select version() into param1; #將版本的信息賦值給 param1
-> end
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> call getversion(@a); #調用getversion()這個存儲過程
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> select @a;
-> //
+--------------------------+
| @a |
+--------------------------+
| 5.1.14-beta-community-nt |
+--------------------------+
1 row in set (0.00 sec)
2、 顯示」hello world」
執行結果
mysql> delimiter //
mysql> create function display(w varchar(20)) returns varchar(50)
-> begin
-> return concat('hello 『,w);
-> end
-> //
Query OK, 0 rows affected (0.05 sec)
mysql> select display("world");
-> //
+------------------+
| display("world") |
+------------------+
| hello world |
+------------------+
1 row in set (0.02 sec)
其他操作存儲過程的語句
前面我們已經知道了怎麼創建存儲過程,下面看看其他常用的用於操作存儲過程的語句。
Alter {procere | function} sp_Name []
Alter 語法是用來改變一個過程或函數的特徵,當你想改變存儲過程或者函數的結構時可以使
用它。當然你也可以先 drop 它再 create。
Drop {procere | function} [if exists] sp_Name
Drop 語法即用來刪除一個存儲程序或者函數,當你創建的一個存儲過程或者函數的名字已經存
在時,你想把以前的給覆蓋掉,那麼此時你就可以使用 drop ,然後在創建。
Show create {procere | function } sp_Name
Show 語法用來顯示創建的存儲過程或者函數的信息。這里的 show 用法跟數據表中的 show 用
法是很相似的。
Show {procere | function} status [like 'partten']
它返回子程序的特徵,如資料庫,名字,類型,創建者及創建和修改日期。如果沒有指定樣式,
根據你使用的語句,所有存儲程序和存儲函數的信息都被列出。
看了以上的幾個語法,你是不是感覺跟對表的操作很相象,那你就想對了,他們確實是很相似
的。帶著一份激動心情我們繼續往下看,你會發現很簡單。
Begin ... End 語句
通過 begin end 可以來包含多個語句,每個語句以「;」結尾。
Declare
用Declare 來聲明局部變數
Declarevar_Name type defaulevaule
Delare 條件
Declarecondition_Name CONDITION FOR condition_value
調用存儲過程
Call
格式:
Callsp_Name [parameter ]
這里的 sp_Name 必須是由 create procere 創建的名稱。它可以通過聲明的參數來傳回值,
它也返回受影響的行數,在 MySQL 中可以通過 mysql_affected_rows() 來獲得。
流程式控制制語句
IF 語句
IFsearch_condition THENstatement_list
[ELSEIFsearch_condition THENstatement_list]
[ELSEstatement_list]
END IF
CASE 語句
CASE case_value
WHEN when_value THENstatement_list
WHEN when_value THENstatement_list]
ELSEstatement_list]
END CASE
LOOP 語句
[begin_label:] LOOP
statement_list
END LOOP [end_label]
LOOP 實現了一個簡單的循環,通過 LEAVE 來退出
LEAVE 語句
LEAVE lable
退出語句,一般可以用在循環中。
ITERATE 語句
ITERATE lable
ITERATE 一般出現在 LOOP、REPEATE、WHILE 里,意思是再次循環。
REPEATE 語句
[begin_label:] REPEAT
statement_list
UNTILsearch_condition
END REPEAT [end_label]
REPEAT 語句內的語句或語句群被重復,直至 search_condition 為真。
WHILE 語句
[begin_label:] WHILEsearch_condition DO
statement_list
END WHILE [end_label]
WHILE 語句內的語句或語句群被重復,直至 search_condition 為真。
運用實例
下面通過幾個例子來講述他們的應用:
對網站用戶的操作
為了簡單,用戶表只有用戶名和密碼的信息.在服務端,我們建立如下的表:
代碼片段
Drop table if exists user;
Create table user(
Id int unsigned not null auto_increment,
Name varchar(20) not null,
Pwd char(32) not null,
Primary key(Id)
);
添加用戶的存儲過程:
代碼片段
Delimiter //
Create procere insertuser(in username varchar(20),in userpwd varchar(32))
Begin
Insert into welefen.user(Name,Pwd) values (username,md5(userpwd));
End
//
驗證用戶的存儲過程:
代碼片段
Delimiter //
Create procere validateuser(in username varchar(20),out param1)
Begin
Select Pwd into param1 from welefen.user where Name=username;
End
//
修改密碼的存儲過程:
代碼片段
Delimiter //
Create procere modifyPwd(in username varchar(20),in userpwd varchar(32))
Begin
Update welefen.user set Pwd=md5(userpwd) where Name=username;
End
//
刪除用戶的存儲過程:
代碼片段
Delimiter //
Create procere deleteuser(in username varchar(20))
Begin
delete from welefen.user where Name=username;
End
//
在客戶端,我們給出如下的程序:
代碼片段
文件名:ProcereUser.php
<?php
if (!mysql_connect("localhost","root","welefen")){
echo "連接資料庫失敗";
}
if (!mysql_select_db("welefen")){
echo "選擇資料庫表失敗<br>";
}
$insert_user=array("welefen","welefen");//這里的welefen分別為用戶名、密碼
if (mysql_query("call insertuser('$insert_user[0]','$insert_user[1]')")){
echo "添加用戶$insert_user[0]成功<br>";
}else {
echo "添加用戶$insert_user[0]失敗<br>";
}
$validate_user=array("welefen","welefen");//這里的welefen分別為用戶名、密碼
mysql_query("call validateuser('$validate_user[0]',@a)");
$Pwd=mysql_query("select @a");
$result=mysql_fetch_array($Pwd);
if ($result[0]==md5($validate_user[1])){
echo "用戶$validate_user[0]驗證正確<br>";
}else {
echo "用戶$validate_user[0]驗證錯誤<br>";
}
$modify_Pwd=array("welefen","weilefeng"); //welefen為用戶名weilefeng為新密碼
if (mysql_query("call modifyPwd('$modify_Pwd[0]','$modify_Pwd[1]')")){
echo "用戶$modigy_Pwd[0]的密碼修改成功<br>";
}else {
echo "用戶$modigy_Pwd[0]的密碼修改失敗<br>";
}
$delete_user=array("welefen"); //welefen為用戶名
if (mysql_query("call deleteuser('$delete_user[0]')")){
echo "用戶$delete_user[0]刪除成功<br>";
}else {
echo "用戶$delete_user[0]刪除失敗<br>";
}
?
程序運行的結果:
執行結果
添加用戶welefen 成功
用戶welefen 驗證正確
用戶welefen 的密碼修改成功
用戶welefen 刪除成功
以上的這個程序簡單的說明了Mysql 中的存儲過程結合PHP 的應用,當然在實際應用要比這個
復雜的多。
驗證角谷猜想
角谷猜想:給定一個整數x,若x%2=1,則x=3*x+1,否則x=x/2,如此循環下去,經過有限步驟必
能得到1。
例 如 : 初 始 整 數 為 9 , 則
9->28->14->7->22->11->34->17->52->26->13->40->20->10->5->16->8->4->2->1
為了說明存儲過程中一些語法的應用,我們通過存儲過程來實現它:
執行結果
mysql> delimiter //
mysql> create procere jgguess(in number int)
-> begin
-> declare param1 int default 1;
-> set @a=concat(number);
-> jiaogu:loop #循環開始
-> set param1=number%2;
-> if param1=1 then set number=number*3+1; #number 為奇數,將它乘3加 1
-> else set number=number/2;
-> end if;
-> set @a=concat(@a,'->',number);
-> if number>1 then iterate jiaogu; #number 不為 1,繼續循環
-> end if;
-> leave jiaogu; #退出循環
-> end loop jiaogu;
-> end
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> call jgguess(11);
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> select @a//
+-------------------------------------------------------+
| @a |
+-------------------------------------------------------+
| 11->34->17->52->26->13->40->20->10->5->16->8->4->2->1 |
+-------------------------------------------------------+
1 row in set (0.02 sec)
在這個存儲過程中,你傳入的參數不能超過int 型數據的范圍,否則就會報錯。
觸發器
觸發器是與表有關的命名資料庫對象,當表上出現特定事件時,將激活該對象。例如當我們向
某個表插入一行數據時發生一個事件或者刪除某個記錄時觸發某個事件。
語法:
CREATE TRIGGER trigger_Name trigger_time trigger_event
ON tbl_Name FOR EACHROW trigger_stmt
trigger_time 是觸發器的動作時間。它可以是 BEFORE 或 AFTER ,以指明觸發器是在激活它的
語句之前或之後觸發。
trigger_event 指明了激活觸發器的語句的類型。trigger_event 可以是下述值之一:
INSERT:將新行插入表時激活觸發器,例如,通過 INSERT、LOADDATA 和 REPLACE 語句;
UPDATE:更改某一行時激活觸發器,例如,通過UPDATE語句;
DELETE:從表中刪除某一行時激活觸發器,例如,通過 DELETE 和 REPLACE 語句。
例如當我們向上面的user 表中增加一個用戶名為「welefen 」時,我們把記錄用戶數的表的值增
加 1;
代碼片段
Create table numuser(
Num int not null default 0
);
Delimiter //
Create trigger testnum after insert on welefen.user for each row
Begin
Update welefen.numuser set Num=Num+1;
End
//
視圖
當我們想得到數據表中某些欄位的信息,並想把他們保存時我們就可以用視圖。
語法:
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_Name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
例如我們想對上面的用戶表使用視圖,可以這樣:
Create viewwelefen.userview as select * fromwelefen.user;
查看視圖的信息可以使用:
Select * fromwelfen.userview;
❻ mysql調用存儲過程刪除數據
創建:
delimiter //
create procere my_add(IN a int, IN b int, OUT c int)
begin
if a is null then set a = 0;
end if;
if b is null then set b = 0;
end if;
set c = a + b;
end;
//
delimiter ;
查看:
方法一:(直接查詢,比較實用,查看當前自定義的存儲過程)
select `specific_name` from mysql.proc where `db` = 'your_db_name' and `type` = 'procere'
方法二:(查看資料庫里所有存儲過程+內容)
show procere status;
方法三:(查看當前資料庫里存儲過程列表)
select specific_name from mysql.proc ;
方法四:(查看某一個存儲過程的具體內容)
select body from mysql.proc where specific_name = 'your_proc_name';
查看存儲過程或函數的創建代碼 :
show create procere your_proc_name;
show create function your_func_name;
調用:
mysql> set @a = 10;
Query OK, 0 rows affected (0.00 sec)
mysql> set @b = 20;
Query OK, 0 rows affected (0.00 sec)
mysql> set @c = 0;
Query OK, 0 rows affected (0.00 sec)
mysql>select @c;
+------+
| @c |
+------+
| 0 |
+------+
mysql> call my_add(@a, @b, @c);
Query OK, 0 rows affected (0.00 sec)
mysql> select @a, @b, @c;
+------+------+------+
| @a | @b | @c |
+------+------+------+
| 10 | 20 | 30 |
+------+------+------+
1 row in set (0.00 sec)
刪除
drop procere your_proc_name;
❼ MySQL裡面sql語句調用存儲過程,該如何寫
這樣:
CREATEPROCEDUREsp_add(a int, b int,outc int)
begin
set c=a+ b;
end;
調用過程:
call sp_add (1,2,@a);
select @a;
(7)mysql資料庫存儲過程教程擴展閱讀:
注意事項
存儲過程(stored procere)是一組為了完成特定功能的SQL語句集合,經編譯後存儲在伺服器端的資料庫中,利用存儲過程可以加速SQL語句的執行。
存儲過程分為系統存儲過程和自定義存儲過程。
系統存儲過程在master資料庫中,但是在其他的資料庫中可以直接調用,並且在調用時不必在存儲過程前加上資料庫名,因為在創建一個新資料庫時,系統存儲過程在新的資料庫中會自動創建。
自定義存儲過程,由用戶創建並能完成某一特定功能的存儲過程,存儲過程既可以有參數又有返回值,但是它與函數不同,存儲過程的返回值只是指明執行是否成功,並不能像函數那樣被直接調用,只能利用execute來執行存儲過程。
創建存儲過程
SQL Server創建存儲過程:
create procere 過程名
@parameter 參數類型
@parameter 參數類型
。。。
as
begin
end
執行存儲過程:execute 過程名