什麼是儲存常式?
儲存常式是儲存在資料庫教程伺服器中的一組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