2008年5月28日 星期三

prepared statement

引用網址:
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

prepared statement

prepared statement是什麼?

Prepared statement 可以讓你在第一次執行時sql時,先設定sql敘述,讓以後相同的sql,只要帶入不同的參數,就重複執行相同的sql,而不用每次執行相同的sql時都讓伺服器耗費時間設定sql敘述。

例子:底下是一個prepared statement的實際範例。

select * from news where id=?

符號? 叫做placeholder

執行sql時,必須代入參數,取代 ? 號,才能真正執行sql敘述。

為什麼要使用prepared statement
程式中使用prepared statement 可以增進安全性及效能。

Prepared statement 把sql的邏輯語句及代入的資料分離,可以增加安全性,這樣的做法,可以避免sql隱碼的攻擊,如果使用一般的sql敘述,沒有分離sql邏輯及代入資料,你必須非常小心處理使用者輸入的資料,通常會使用一些特定的函數,跳脫單引號、雙引號、倒斜線等特殊字元。但是當使用prepared statement時,根本不用使用特殊的函數來避免sql隱碼的攻擊,你可以直接使用prepared statement,不會造成任何sql隱碼的漏洞。

效能的提升來自prepared statement的一些特殊之處,首先,prepared statement中的sql敘述只要解析一次,之後執行的sql敘述就不用再做這些解析的動作,如果你要執行同一個sql敘述很多次,就可以增加執行的速度。

效能提升的第二個原因,是prepared statement使用了binary protocol,傳統的mysql會將資料轉換成字串,再進行傳送,但使用binary protocol後,不會進行資料的轉換,而是直接將資料以原來的binary的型式進行傳送,減低了cpu的負荷,也減少了網路的使用率(轉換成字串,資料量會變大)。

使用prepared statement 的時機
prepared statement只能用在DML(insert,update,delete,replace),create table,select敘述上,額外的支援會再慢慢加上去。

Prepared statement因為要解析兩次,會比一般的sql敘述慢,如果sql敘述只會執行一次,你就要考量,是否值得使用prepared statement增強安全性,而犧牲了整體的執行速度。

如何使用prepared statement
php 5的mysqli extention支援prepared statement,其他的語言我不熟。

Mysql也有使用prepared statement的interface,不過這些interface不支援binary protocol,除非程式語言的api不支援,不然,mysql的prepared statement interface通常當做測試用。

Mysql的prepared statement的interface的用法

create table people(name,sex);

insert into people(name,sex) values('Hi','f'),('a','b');

set @query='select * from people where name=? And sex=?';

set @name='Hi';

set @sex='f';

prepare stmt from @query;

execute stmt using @name,@sex;

2008年5月27日 星期二

trigger


引用網址

http://dev.mysql.com/doc/refman/5.0/en/triggers.html#nolinkhere

trigger

概論:
trigger是資料庫中的一種物件,trigger物件的運作與資料表息息相關,當對資料表執行insert、update或delete的動作時才會觸發指定的trigger物件,執行trigger內的sql敘述,底下以實例說明會比較清楚:

#建立一個資料表,名稱是employ

create table employ(hour int,net_pay int);


#建立一個與employ資料表相關的trigger,名稱是tri_cal
#這個trigger的作用是當插入資料到資料表employ中時,變數sum的值會與資料表employ
#中的新揷入的欄位net_pay的值相加。

create trigger tri_cal
before insert
on employ
for each row
set @sum=@sum+new.net_pay;



#變數sum的值會變成2

set @sum=0;
insert imploy(hour,net_pay) values(1,2);
select @sum;


#變數sum的值會變成4

insert imploy(hour,net_pay) values(1,2);
select @sum;


語法說明:
create [definer={usercurrent_user}] trigger trigger_name
trigger_time trigger_event
on table_name
for each row
trigger_stmt


trigger_time
before
after

trigger_event
insert
update
delete


table_name
指定觸發trigger的table


trigger_stmt
觸發後執行的sql敘述