MySQL函式及儲存過程
阿新 • • 發佈:2021-10-17
MySQL函式及儲存過程
- 參考文章:
https://www.cnblogs.com/wupeiqi/articles/5713323.html
1、函式
1.1內建函式
- 官方文件:
https://dev.mysql.com/doc/refman/5.7/en/functions.html
CHAR_LENGTH(str) 返回值為字串str 的長度,長度的單位為字元。一個多位元組字元算作一個單字元。 對於一個包含五個二位元組字符集, LENGTH()返回值為 10, 而CHAR_LENGTH()的返回值為5。 CONCAT(str1,str2,...) 字串拼接 如有任何一個引數為NULL ,則返回值為 NULL。 CONCAT_WS(separator,str1,str2,...) 字串拼接(自定義連線符) CONCAT_WS()不會忽略任何空字串。 (然而會忽略所有的 NULL)。 CONV(N,from_base,to_base) 進位制轉換 例如: SELECT CONV('a',16,2); 表示將 a 由16進位制轉換為2進位制字串表示 FORMAT(X,D) 將數字X 的格式寫為'#,###,###.##',以四捨五入的方式保留小數點後 D 位, 並將結果以字串的形式返回。若 D 為 0, 則返回結果不帶有小數點,或不含小數部分。 例如: SELECT FORMAT(12332.1,4); 結果為: '12,332.1000' INSERT(str,pos,len,newstr) 在str的指定位置插入字串 pos:要替換位置其實位置 len:替換的長度 newstr:新字串 特別的: 如果pos超過原字串長度,則返回原字串 如果len超過原字串長度,則由新字串完全替換 INSTR(str,substr) 返回字串 str 中子字串的第一個出現位置。 LEFT(str,len) 返回字串str 從開始的len位置的子序列字元。 LOWER(str) 變小寫 UPPER(str) 變大寫 LTRIM(str) 返回字串 str ,其引導空格字元被刪除。 RTRIM(str) 返回字串 str ,結尾空格字元被刪去。 SUBSTRING(str,pos,len) 獲取字串子序列 LOCATE(substr,str,pos) 獲取子序列索引位置 REPEAT(str,count) 返回一個由重複的字串str 組成的字串,字串str的數目等於count 。 若 count <= 0,則返回一個空字串。 若str 或 count 為 NULL,則返回 NULL 。 REPLACE(str,from_str,to_str) 返回字串str 以及所有被字串to_str替代的字串from_str 。 REVERSE(str) 返回字串 str ,順序和字元順序相反。 RIGHT(str,len) 從字串str 開始,返回從後邊開始len個字元組成的子序列 SPACE(N) 返回一個由N空格組成的字串。 SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len) 不帶有len 引數的格式從字串str返回一個子字串,起始於位置 pos。帶有len引數的格式從字串str返回一個長度同len字元相同的子字串,起始於位置 pos。 使用 FROM的格式為標準 SQL 語法。也可能對pos使用一個負值。假若這樣,則子字串的位置起始於字串結尾的pos 字元,而不是字串的開頭位置。在以下格式的函式中可以對pos 使用一個負值。 mysql> SELECT SUBSTRING('Quadratically',5); -> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4); -> 'barbar' mysql> SELECT SUBSTRING('Quadratically',5,6); -> 'ratica' mysql> SELECT SUBSTRING('Sakila', -3); -> 'ila' mysql> SELECT SUBSTRING('Sakila', -5, 3); -> 'aki' mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2); -> 'ki' TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str) TRIM(remstr FROM] str) 返回字串 str , 其中所有remstr 字首和/或字尾都已被刪除。若分類符BOTH、LEADIN或TRAILING中沒有一個是給定的,則假設為BOTH 。 remstr 為可選項,在未指定情況下,可刪除空格。 mysql> SELECT TRIM(' bar '); -> 'bar' mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx'); -> 'barxxx' mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx'); -> 'bar' mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz'); -> 'barx' 部分內建函式
1.2自定義函式
-
語法
delimiter \\ -- 修改結束符 create function f1( -- 建立函式的命令 i1 int, i2 int) -- 定義引數: 引數的型別必須是表名裡面有的 returns int -- 定義返回值型別 BEGIN -- 函式體開始 -- 注意:函式體內不能寫select * from table declare num int; -- 聲名變數 -- declare num int default 0; --聲名變數並設定預設值是一 set num = i1 + i2;-- 執行相加操作 return(num);-- 返回num END \\-- 函式體結束 delimiter ; -- 修改回結束符
- 報錯解決方式
-
-- MYSQL 函式 -- 內建函式 -- 函式的使用,在select後面使用 -- 顯示建立日期 SELECT CURRENT_DATE() -- 日期格式化,常用 -- use prozhjy SELECT 時間,count(1) from 任務點途徑 GROUP BY DATE_FORMAT(時間,"%Y-%m") SELECT DATE_FORMAT(時間,"%Y-%m-%d") FROM `任務點途徑` -- 自定義函式 delimiter \\ CREATE FUNCTION f1 ( i1 INT, i2 INT ) RETURNS INT BEGIN DECLARE num INT; SET num = i1 + i2; RETURN ( num ); END \\ delimiter; -- 刪除函式 drop function func_name; -- 執行函式 # 獲取返回值 declare @i VARCHAR(32); select UPPER('alex') into @i; SELECT @i; # 在查詢中使用 select f1(11,nid) ,name from tb2;
2、儲存過程
2.1 .簡單儲存過程的建立
-- 儲存過程
-- 個人理解:一堆SQL語句的操作進行集合
-- 分類
-- 簡單建立
-- 建立儲存過程
delimiter //
create procedure p1() -- 建立命令
BEGIN
select * from student; -- 命令體
END//
delimiter ;
-- 執行儲存過程
call p1()
-- 無引數儲存過程
2.2. 有引數的儲存過程
-
引數分類
- out 僅用於返回值(注:一般作為執行成功返回的標誌)
- in 僅用於傳入引數
- inout 既可以當做傳入引數,也可以當做返回值來用
-
刪除儲存過程:
DROP PROCEDURE pro_name
-- ============================================== -- 建立儲存過程 -- delimiter \\ -- create procedure p2( -- in i1 int,-- 傳入引數 -- -- in i2 int, -- -- inout i3 int,-- 既可以傳入也可以傳出的引數 -- out r1 int -- 傳出引數 -- ) -- BEGIN -- -- 聲名變數型別 -- -- DECLARE n2 int; -- -- DECLARE temp2 int default 0; -- -- -- 聲名session級別的變數呼叫是使用@ -- -- set temp1 = 1; -- -- -- set r1 = i1 + i2 + temp1 + temp2; -- SELECT * from student; -- -- set i3 = i3 + 100; -- set r1 =i1+1 -- end\\ -- delimiter ; -- -- -- 執行儲存過程 -- -- 聲名session變數 -- -- set @t1 =4; -- set @t2 = 0; -- CALL p1 (1,@t2); -- SELECT @t2; -- 有引數的儲存過程 -- ************************************** -- 有引數的儲存過程 delimiter \\ CREATE PROCEDURE p3( in n1 int, out n2 int ) BEGIN set n2=123123; SELECT * from student WHERE sid>n1; END \\ delimiter ; set @v1=123; call p3(2,@v1); SELECT @v1;
2.3事務
-- 事務
delimiter \\
CREATE PROCEDURE p4(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for SQLEXCEPTION
BEGIN
-- error檢測異常,事物回滾
set p_return_code=1;
ROLLBACK;
END
-- DECLARE EXIT handler for SQLWARNING
-- BEGIN
-- -- waring,使用較少
-- set p_return_code=2;
-- ROLLBACK;
-- END
-- 開始事物
START TRANSACTION
DELETE from teacher WHERE tname='程心';
INSERT into teacher(tname)VALUES('章北海');
COMMIT;
-- 提交事物
-- success
set p_return_code=0;
END \\
delimiter ;
set @v2=123;
call p4(@v2);
SELECT @v2;
SELECT * from teacher
2.4 遊標
delimiter \\
CREATE PROCEDURE p5()
BEGIN
DECLARE ssid int;-- 定義變數
DECLARE ssname VARCHAR(50);-- 自定義變數2
-- 設定標誌,用來檢測遊標內是否還有資料,預設為flase
DECLARE done INT DEFAULT FALSE;
-- 定義遊標 語法
DECLARE my_cursor CURSOR FOR SELECT sid,sname FROM student;
-- 當遊標內沒有資料的時候將done設定為TRUE
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
OPEN my_cursor;
xxyy:loop
FETCH my_cursor into ssid,ssname;
IF done THEN
LEAVE xxyy;
END IF;
INSERT into teacher (tname) VALUES (ssname);
END loop xxyy;
CLOSE my_cursor;
END\\
delimiter ;
-- =====================
-- 呼叫遊標
call p5()
SELECT * from teacher;
SELECT * from student;
2.5 使用pymysql呼叫儲存過程
-
無參呼叫
# -*- coding: utf-8 -*- ''' @Time : 2021/10/17 19:22 @Author : ziqingbaojian @File : sqlcon.py ''' import pymysql try: conn=pymysql.connect(host='127.0.0.1',user='root',password='1234567',database='testlearn') except Exception as e: print(e) cur=conn.cursor() # cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)查詢結果以字典的形式進行返回 # 普通查詢 ''' sqlstr="select * from student where sid>%s" cur.execute(sqlstr,3) res=cur.fetchall() print(res) ''' # 呼叫無參的儲存過程 cur.callproc('p1') res=cur.fetchall() print(res)
-
引數呼叫
# -*- coding: utf-8 -*- ''' @Time : 2021/10/17 19:22 @Author : ziqingbaojian @File : sqlcon.py ''' import pymysql try: conn=pymysql.connect(host='127.0.0.1',user='root',password='1234567',database='testlearn') except Exception as e: print(e) cur=conn.cursor() # 呼叫有參儲存過程 # 執行儲存過程 cur.callproc('p3',(2,123)) # 獲取執行完儲存的引數 # 接收儲存過程中查詢結果 res=cur.fetchall() print(res) # 儲存過程返回的結果 # 固定 引數寫法:@_pname_0,@_pname_1,..... cur.execute("select @_p3_0,@_p3_1;") result = cur.fetchall() conn.commit() cur.close() conn.close() print(result)
今天你學習了嗎?