什麼是存儲例程?
存儲例程是存儲在數據庫教程服務器中的一組sql語句,通過在查詢中調用一個指定的名稱來執
行這些sql語句命令。
為什麼要使用存儲過程?
我們都知道應用程序分為兩種,一種是基於web,一種是基於桌面,他們都和數據庫進行交
互來完成數據的存取工作。假設現在有一種應用程序包含了這兩種,現在要修改其中的一個
查詢sql語句,那麼我們可能要同時修改他們中對應的查詢sql語句,當我們的應用程序很龐
大很復雜的時候問題就出現這,不易維護!另外把sql查詢語句放在我們的web程序或桌面中
很容易遭到sql注入的破壞。而存儲例程正好可以幫我們解決這些問題。
存儲過程(stored procedure)、存儲例程(store routine)、存儲函數區別
Mysql存儲例程實際包含了存儲過程和存儲函數,它們被統稱為存儲例程。
其中存儲過程主要完成在獲取記錄或插入記錄或更新記錄或刪除記錄,即完成select
insert delete update等的工作。而存儲函數只完成查詢的工作,可接受輸入參數並返回一
個結果。
創建存儲過程、存儲函數
create procedure 存儲過程名(參數)
存儲過程體
create function 存儲函數名(參數)
存儲函數體
假設現在有一個數據庫omcmc中的表db_info 表結構如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for db_news
-- ----------------------------
DROP TABLE IF EXISTS `db_news`;
CREATE TABLE `db_news` (
`id` int(10) NOT NULL auto_increment,
`title` varchar(200) NOT NULL,
`editor` varchar(20) default NULL,
`origin` varchar(20) default NULL,
`tags` varchar(200) default NULL,
`content` text NOT NULL,
`hits` int(10) default '0',
`ip` varchar(15) NOT NULL,
`time` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;-- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `db_news` VALUES ('1', First App', 'xqbar.com', 'xqbar.com', 'omcmc','detail。。', '100', '127.0.0.1', '1215051225');
使用上面的表我們創建一個簡單的存儲過程
create procedure select_news()
select title,hits from db_news;
在終端運行並調用
從上面的截圖我們看到如何調用我們的存儲過程
調用存儲過程
call 存儲過程名();
以上我們創建了一個簡單的存儲過程,當然我們的應用程序不可能使用這麼簡單的存儲過程
,我們需要的是能給存儲過程傳遞參數,以返回給我們所需要的結果數據。下面就了解下存
儲過程的參數。
存儲過程的參數
通常存儲過程接受用戶的參數,返回結果給調用用戶。
mysql教程規定對於存儲過程的參數要求其每個參數都必須聲明其參數名,數據類型以及該參數是
輸入參數還是用於返回信息還是兩者兼有,對於存儲函數php教程只支持輸入參數。
聲明參數時規定要使用關鍵字IN,OUT,INOUT。
其中:
IN:用於輸入參數
OUT:用於返回參數
INOUT:用於向存儲過程傳遞參數值,如果該值改變則返回
另外規定對於聲名為OUT,INOUT的參數當我們調用存儲過程時需要在參數名前加@,以確保參
數在過程外調用,下面我們修改上面的存儲過程以傳遞信息編號給存儲過程select_news,返
回對應的信息標題給我們查看。
drop procedure if exists select_news;
create procedure select_news(IN id int,OUT title varchar(200))
select db_news.title from db_news where db_news.id=id;在終端運行並調用
注意調用格式
call select_news(1,@title);
其中1是我們要傳入的信息編號,title是要返回的對應信息編號標題,由於是OUT所以再調用時要在其前加@在過程外調用。(見下例)
drop procedure if exists getNum;
create procedure getNum(OUT num int)
select 100 into num;call getNum(@num);
select @num;
截圖:
php存儲例程、存儲過程進階學習之二
接著上篇文章,再調用有返回值時上個例子我們可以使用以下的方法調用存儲過程:
select @返回參數;
我們現在使用這個方法來調用上面我們創建的select_news,來看看
有人會疑問為什麼返回的title是null,而不是像call select_news(1,@title)一樣返回的是
我們數據庫編號對應的數據First App,這是由於我們的存儲過程體並沒有給title返回參數返
回值。
下面我們來看看存儲函數
仍然以db_news表為例說明,不過我們在這個存儲函數中我們加入其他一些關於存儲例程的知
識來引入我們這次要談及的學習對象。
drop function if exists count_news;
delimiter //
create function count_news(hits int) returns int
comment '根據傳入的點擊次數統計超過此點擊數的信息數目'
begin
declare total_news int;
declare hits_num int default 0;
if hits>=0 then
set hits_num=hits;
select count(id) into total_news from db_news where db_news.hits>hits_num;
else
set total_news=0;
end if;
return total_news;
end;
//
delimiter ;
在上面的存儲函數中我們使用到了存儲例程變量的聲明、設置其值、判斷語句、存儲函數特
有的返回值類型及存儲例程如何描述(comment).
與存儲過程返回參數不同的是存儲函數在定義時沒用直接聲明哪個變量是返回參數,而只是
使用了returns聲明了返回參數所屬的數據類型,返回參數是在函數體中使用return返回要返
回的數據變量的形式來表示的。這就需要注意的是:
存儲函數只支持輸入參數,並且輸入參數前沒有IN或INOUT.
返回上面的存儲函數,我們來解釋下代碼含義:
drop function if exists count_news;
如果存在存儲函數count_news則刪除該存儲函數,與存儲過程一樣我們可以使用下面的語句
刪除存儲過程或函數
drop procedure|function [if exists] 存儲過程名|存儲函數名;
delimiter //
使用delimiter更改mysql默認使用分號(;)使用新的結束符號來結束當前語句,使用
delimiter後原先默認的分號(;)結束語句符號不再起作用,直到重新恢復聲明結束符後。
create function count_news(hits int) returns int
注意存儲函數的參數只有輸入參數並且前不再聲明IN或INOUT,返回只需聲明要返回的數據類
型
comment '根據傳入的點擊次數統計超過此點擊數的信息數目'
使用comment 來描述該存儲過程或存儲函數的功能信息。使用格式為 comment '描述字符串
'
begin
使用begin限定一個處理模塊
declare total_news int;
聲明變量 格式 declare 變量名 數據類型 [default 默認值]
declare hits_num int default 0;
聲明變量 格式 declare 變量名 數據類型 [default 默認值]
if hits>=0 then
set hits_num=hits;
使用set 給變量賦值
select count(id) into total_news from db_news where db_news.hits>hits_num;
sql語句可以使用into給變量賦值
else
set total_news=0;
end if;
上面是一個判斷語句,注意格式為if-else-end if 或者 if –else if-else-end if
注意分號(;)
return total_news;
使用return 返回存儲函數要返回的值,注意該值只能是一個值。
end;
//
delimiter ;
綜合一下我們上面的概念知識:
1. 存儲函數的參數與存儲過程有何不同。
2. 在存儲例程中如何更改mysql的默認結束符號。
3. 在存儲例程中如何描述功能信息。
4. 聲明、設置變量。
5. begin-end語句塊。
6. 條件判斷if-else if-else-end if 或if-else-end if 或者if-end if