mysql 5.0預存程序學習總結
一.建立預存程序
1.基本文法:
create procedure sp_name()
begin
end
2.參數傳遞
二.調用預存程序
1.基本文法:call sp_name()
注意:預存程序名稱後面必須加括弧,哪怕該預存程序沒有參數傳遞
三.刪除預存程序
1.基本文法:
drop procedure sp_name//
2.注意事項
(1)不能在一個預存程序中刪除另一個預存程序,只能調用另一個預存程序
四.區塊,條件,迴圈
1.區塊定義,常用
begin
end;
也可以給區塊起別名,如:
lable:begin
end lable;
可以用leave lable;跳出區塊,執行區塊以後的代碼
2.條件陳述式 3.迴圈語句 :while迴圈 loop迴圈 repeat until迴圈 repeat until迴圈
五.其他常用命令
1.show procedure status
顯示資料庫中所有儲存的預存程序基本資料,包括所屬資料庫,預存程序名稱,建立時間等
2.show create procedure sp_name
顯示某一個預存程序的詳細資料
mysql預存程序基本函數
一.字串類
CHARSET(str) //返回字串字元集
CONCAT (string2 [,... ]) //串連字串
INSTR (string ,substring ) //返回substring首次在string中出現的位置,不存在返回0
LCASE (string2 ) //轉換成小寫
LEFT (string2 ,length ) //從string2中的左邊起取length個字元
LENGTH (string ) //string長度
LOAD_FILE (file_name ) //從檔案讀取內容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定開始位置
LPAD (string2 ,length ,pad ) //重複用pad加在string開頭,直到字串長度為length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重複count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //在str後用pad補充,直到長度為length
RTRIM (string2 ) //去除後端空格
STRCMP (string1 ,string2 ) //逐字元比較兩字串大小,
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字元,
即參數position必須大於等於1
TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字元
UCASE (string2 ) //轉換成大寫
RIGHT(string2,length) //取string2最後length個字元
SPACE(count) //產生count個空格
二.數學類
ABS (number2 ) //絕對值
BIN (decimal_number ) //十進位轉二進位
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //進位轉換
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小數位元
HEX (DecimalNumber ) //轉十六進位
註:HEX()中可傳入字串,則返回其ASC-11碼,如HEX(’DEF’)返回4142143
也可以傳入十進位整數,返回其十六進位編碼,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求餘
POWER (number ,power ) //求指數
RAND([seed]) //隨機數
ROUND (number [,decimals ]) //四捨五入,decimals為小數位元]
三.日期時間類
ADDTIME (date2 ,time_interval ) //將time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //轉換時區
CURRENT_DATE ( ) //當前日期
CURRENT_TIME ( ) //目前時間
CURRENT_TIMESTAMP ( ) //目前時間戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或時間
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式顯示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上減去一個時間
DATEDIFF (date1 ,date2 ) //兩個日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1為星期天
DAYOFYEAR (date ) //一年中的第幾天
EXTRACT (interval_name FROM date ) //從date中提取日期的指定部分
MAKEDATE (year ,day ) //給出年及年中的第幾天,產生日期串
MAKETIME (hour ,minute ,second ) //產生時間串
MONTHNAME (date ) //英文月份名
NOW ( ) //目前時間
SEC_TO_TIME (seconds ) //秒數轉成時間
STR_TO_DATE (string ,format ) //字串轉成時間,以format格式顯示
TIMEDIFF (datetime1 ,datetime2 ) //兩個時間差
TIME_TO_SEC (time ) //時間轉秒數]
WEEK (date_time [,start_of_week ]) //第幾周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第幾天
HOUR(datetime) //小時
LAST_DAY(date) //date的月的最後日期
MICROSECOND(datetime) //微秒
MONTH(datetime) //月
MINUTE(datetime) //分
## **********first test,procedure**********
#<1>
use testprocedure;
delimiter //
create procedure simpleproce1 (out par1 int)
begin
select count(*) into par1 from proce;
end
//
delimiter ;
call simpleproce1(@a);
select @a;
#<2>,每次只有單一的行可以被取回select id,name into par1,par2 from proce LIMIT 1;中的LIMIT 1;
use testprocedure;
delimiter //
DROP procedure IF EXISTS simpleproce2
create procedure simpleproce2 (out par1 int,out par2 char(30))
begin
select id,name into par1,par2 from proce LIMIT 1;
end
//
delimiter ;
call simpleproce2(@a,@b);
select @a,@b;
## *********second test,function************
#<3>
delimiter //
DROP FUNCTION IF EXISTS hello
//
create function hello(s char(20)) returns char(50)
return concat('Hello, ',s,'!');
//
delimiter ;
select hello('world');
show create function testprocedure.hello\G
#它返回子程式的特徵,如資料庫,名字,類型,建立者及建立和修改日期
show function status like 'hello'\G
#<4>
#注意name不能和欄位名相同
delimiter //
DROP procedure IF EXISTS test //
CREATE PROCEDURE test ()
BEGIN
DECLARE name VARCHAR(5) DEFAULT 'bob';
DECLARE newname VARCHAR(5);
DECLARE xid INT;
SELECT name,id INTO newname,xid
FROM proce WHERE name = name;
SELECT newname;
END;
//
call test1() //
#***
delimiter //
DROP procedure IF EXISTS test2 //
CREATE PROCEDURE test2 ()
BEGIN
DECLARE newname VARCHAR(5);
DECLARE xid INT;
SELECT name,id INTO newname,xid
FROM proce limit 1;
SELECT newname,xid;
END;
//
call test2() //
#<5>
use testprocedure;
CREATE PROCEDURE p1 () SELECT * FROM proce;
call p1();
#<6>注意此處的handler是設定SQLSTATE值,SQLWARNING是對所有以01開頭的SQLSTATE代碼的速記
#NOT FOUND是對所有以02開頭的SQLSTATE代碼的速記
#SQLEXCEPTION是對所有沒有被SQLWARNING或NOT FOUND捕獲的SQLSTATE代碼的速記
#DECLARE CONTINUE HANDLER聲明CONTINUE異常處理
#事實上這裡的23000SQLSTATE是更常用的,當外鍵約束出錯或主鍵約束出錯就被調用了。
#當沒有發生該23000異常時, select @x2的值將是null,而不是1,
#並且後面的第2個語句執行時將會報主鍵約束錯誤,此時@x2=1,@x=4,雖然第2句有了異常,但是後面的語句繼續執行
#儲存到資料的資料是3,test3和5,test5
use testprocedure;
delimiter //
DROP procedure IF EXISTS handlerdemo
//
create procedure handlerdemo()
begin
declare continue handler for sqlstate '23000' set @x2=1;
set @x=1;
insert into proce values(3,'test3');
set @x=2;
insert into proce values(3,'test4');
set @x=3;
insert into proce values(5,'test5');
set @x=4;
end;
//
call handlerdemo()//
select @x //
select @x2 //
## ************游標****************
#<7>游標必須在聲明處理常式之前被聲明,並且變數和條件必須在聲明游標或處理常式之前被聲明
#在這裡先聲明變數a,b,c,後聲明cursor
create procedure curdemo()
begin
declare done int default 0;
declare a char(16);
declare b,c int;
declare cur1 cursor for select id,name from proce;
declare cur2 cursor for select id from proce2;
declare continue handler for sqlstate '02000' set done=1;
open cur1;
open cur2;
repeat
fetch cur1 into b,a;
fetch cur2 into c;
if not done then
if b insert into proce3 values(b,a);
else
insert into proce3 values(c,a);
end if;
end if;
until done end repeat;
close cur1;
close cur2;
end
## **************** Case *******************
#<8>when ... then ;case ... end case;
delimiter //
DROP procedure IF EXISTS p13
//
create procedure p13(in par1 int)
begin
declare var1 int;
set var1=par1+1;
case var1
when 0 then insert into casetest values(17);
when 1 then insert into casetest values(18);
else insert into casetest values(19);
end case;
end;
//
call p13(-1)//
call p13(0)//
call p13(1)//
call p13(null)//
## **************** while ****************
#<9>while ... do ... end while;為了防止null的錯誤,set v=0是必須的
delimiter //
DROP procedure IF EXISTS p14
//
create procedure p14()
begin
declare v int;
set v=0;
while v < 5 do
insert into casetest values (v);
set v=v+1;
end while;
end;//
call p14()//
## ***************** repeat *****************
#<10>repeat ...until ... end repeat; 是執行後檢查(until v>=5),而while是執行前檢查(while v<5)
delimiter //
DROP procedure IF EXISTS p15
//
create procedure p15()
begin
declare v int;
set v=0;
repeat
insert into casetest values(v);
set v=v+1;
until v >=5
end repeat;
end;
//
call p15()//
## ***************** loops *****************
#<11> loop 和while一樣不需要初始條件,同時和repeat一樣不需要結束條件
# loop_label: loop
# ...
# if .. then
# leave loop_label
# end if
# end loop
delimiter //
DROP procedure IF EXISTS p16
//
create procedure p16()
begin
declare v int;
set v=0;
loop_label: loop
insert into casetest values(v);
set v=v+1;
if v >=5 then
leave loop_label;
end if;
end loop;
end;//
call p16()//
## ***************** Labels *****************
# <12>labels標號; 注意此處的until 0=0後面沒有分號“;”
delimiter //
DROP procedure IF EXISTS p17//
create procedure p17()
label_1:begin
label_2:while 0=1 do leave label_2; end while;
label_3:repeat leave label_3;until 0=0 end repeat;
label_4:loop leave label_4; end loop;
end;//
call p17()//
#<13>labels 標號結束符;
delimiter //
DROP procedure IF EXISTS p18//
create procedure p18()
label_1:begin
label_2:while 0=1 do leave label_2; end while label_2;
label_3:repeat leave label_3;until 0=0 end repeat label_3;
label_4:loop leave label_4; end loop label_4;
end label_1;//
call p18()//
#<14>leave和labels 跳出和標號;leave 使程式跳出複雜的語句
delimiter //
DROP procedure IF EXISTS p19//
create procedure p19(par char)
label_1:begin
label_2:begin
label_3:begin
if par is not null then
if par='a' then leave label_1;
else
begin
if par='b' then
leave label_2;
else
leave label_3;
end if;
end;
end if;
end if;
end label_3;
end label_2;
end label_1;
//
call p19('a')//
#<15>iterate迭代,必須用leave;iterate意思是重新開始複合陳述式,相當於 continue
#該結果中3將不被儲存到資料庫表中
delimiter //
DROP procedure IF EXISTS p20//
create procedure p20()
begin
declare v int;
set v=0;
loop_label:loop
if v=3 then
set v=v+1;
iterate loop_label;
end if;
insert into casetest values(v);
set v=v+1;
if v>=5 then
leave loop_label;
end if;
end loop loop_label;
end;//
call p20()//
#<16>Grand combination大組合
delimiter //
DROP procedure IF EXISTS p21//
create procedure p21(in par1 int,out par2 int)
language sql deterministic sql security invoker
begin
declare v int;
label goto_label;
start_label:loop
if v=v then
leave start_label;
else
iterate start_label;
end if;
end loop start_label;
repeat
while 1=0 do begin end;
end while;
until v=v
end repeat;
goto goto_label;
end;
//
call p21()//
## **************** trigger ***************************
#<17>
use testprocedure;
CREATE TABLE trig1(a1 int);
CREATE TABLE trig2(a2 int);
CREATE TABLE trig3(a3 int not null AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE trig4(
a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b4 INT DEFAULT 0
);
insert into trig3(a3) values(null),(null),(null),(null),(null),(null),(null),(null),(null),(null);
insert into trig4(a4) values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
delimiter //
DROP trigger trigtest//
create trigger trigtest before insert on trig1
for each row begin
insert into trig2 set a2=NEW.a1;
delete from trig3 where a3=NEW.a1;
update trig4 set b4=b4+1 where a4=NEW.a1;
end;
http://blog.zol.com.cn/893/article_892123.html