環境
DBMS:MySQL 8.0.17
工具:Navicat Premium 11.2.16
存儲過程
存儲過程是由過程化SQL語言書寫的過程,這個過程經編譯和優化后存儲在數據庫服務器中,使用時調用即可。
優點:
- 運行效率高。提供了在服務器端快速執行SQL語句的有效途徑。
- 降低了客戶機和服務器之間的通信量。客戶機上的應用程序只要通過網絡向服務器發出調用存儲過程的名字和參數,就可以執行其中的多條SQL語句並進行數據處理。只有最終的處理結果才返回客戶端。
- 方便實施企業規則。可以把企業規則的運算程序寫成存儲過程放入數據庫服務器中,既有利於集中控制,又能夠方便地進行維護。當企業規則發生變化時只要修改存儲過程即可,無須修改其他應用程序。
創建
CREATE PROCEDURE <存儲過程名>([<參數模式> <參數名> <參數類型>]) BEGIN <SQL塊> END;
存儲過程的參數模式有3種:
- in:參數需要傳入值。
- out:參數可以作為返回值。
- inout:參數既需要傳入值,又可以作為返回值。
調用
CALL <存儲過程名>([<參數>]);
若存儲過程定義了參數,則在調用前需要先聲明變量,然后在調用存儲過程時傳入變量。
定義一個可以根據學號查詢學生信息的存儲過程getStudentBySno,如果傳入的sno為空,則取學號為201215121的學生信息:
聲明用戶變量sno:
調用存儲過程getStudentBySno:
可以看到,傳入的sno為空值,所以查詢的是學號為201215121的學生信息。
也就是說,模式為in的參數能獲取傳入變量的值。
查看用戶變量sno:
可以看到,雖然存儲過程中改變參數sno的值,但並不影響傳入的用戶變量sno的值。
也就是說,作為模式為in的參數傳入存儲過程的變量,在調用存儲過程后不會改變變量的值。
定義一個可以獲取學生人數的存儲過程getCount:
定義用戶變量count:
調用存儲過程getCount:
可以看到,用戶變量的值並沒有傳入存儲過程中。
也就是說,模式為out的參數不能獲取傳入變量的值。
查看用戶變量count:
可以看到,count的值發生了改變。
也就是說,作為模式為out的參數傳入存儲過程的變量,在調用存儲過程后會改變變量的值。
定義一個可以用於求傳入值的平方的存儲過程:
設置用戶變量n:
調用存儲過程getPower:
可以看到,用戶變量的值傳入了存儲過程中。
也就是說,模式為inout的參數能獲取傳入變量的值。
查看用戶變量n:
可以看到,n的值發生了改變。
也就是說,作為模式inout的參數傳入存儲過程的變量,在調用存儲過程后會改變變量的值。
刪除
DROP PROCEDURE <存儲過程名>;
函數
函數與存儲過程類似,都是由過程化SQL語言書寫的過程,這個過程經編譯和優化后存儲在數據庫服務器中。
與存儲過程不同的是:
- 函數有1個返回值,存儲過程沒有返回值。
- 函數是通過select調用,存儲過程是通過call調用。
函數可以分為兩種:
- 單行函數:對應一個記錄就會有一個返回值。
- 統計函數:對應多個記錄有一個返回值。
內置函數
MySQL中有許多內置函數,可以在每個數據庫中直接使用。
單行函數
數值相關
ceil(X):返回數值X上取整的結果。
floor(X):返回數值X下取整的結果。
round(X):返回數值X四舍五入后的整數結果。
round(X, D):返回數值X保留D位小數四舍五入后的結果。
字符串相關
concat(str1, str2, ...):返回拼接后的字符串。
instr(str, substr):返回substr在str中第一次出現的位置,如果沒有出現則返回0。
length(str):返回str的字節個數。
lower(str):將str中的大寫字母變為小寫字母並返回。
lpad(str, len, padstr):若str的長度大於len,則截斷后面的字符,保留前面len個字符並返回;若str的長度小於len,則在str前使用padstr填充直到長度為len並返回。
replace(str, from_str, to_str):將str中的from_str全部替換成to_str並返回。
rpad(str, len, padstr):若str的長度大於len,則截斷前面的字符,保留后面len個字符並返回;若str的長度小於len,則在str后使用padstr填充直到長度為len並返回。
substr(str, pos, len):從第pos個字符開始截取str中之后的至多len個字符並返回。
trim(str):去掉str前后“ ”。
trim(remstr from str):去掉str前后的remstr。
upper(str):將str中的小寫字母變為大寫字母並返回。
日期時間相關
curdate():返回系統日期。
curtime():返回系統時間。
date_format(date, format):將日期按format進行格式化並返回。
datediff(expr1, expr2):返回expr1和expr2相差的天數。
now():返回系統日期時間。
str_to_date(str, format):將日期字符串按format進行解析並返回。
常用日期格式符號
格式 | 描述 |
%Y | 年份(4位) |
%y | 年份(2位) |
%m | 月份(01-12) |
%d | 天數(01-31) |
%H | 時(00-23) |
%i | 分(00-59) |
%s | 秒(00-59) |
%M | 月名 |
%a | 縮寫月名 |
%W | 星期名 |
%b | 縮寫星期名 |
%p | 上午、下午 |
%h | 小時(01-12) |
%T | 24小時制—hh:mm:ss |
%r | 12小時制—hh:mm:ss AM|PM |
其他
database():返回當前數據庫。
if(expr1, expr2, expr3):判斷expr1,如果為真返回expr2,否則返回expr3。
ifnull(expr1, expr2):判斷expr1是否為空值,如果是空值就返回expr2。
user():返回當前用戶。
version():返回版本號。
統計函數
avg([DISTINCT ]expr):統計多個記錄中指定字段的均值(不計空值)。只適用於數值類型的字段。distinct關鍵字用於去掉重復數據的記錄。
count(*):統計記錄數。
count([DISTINCT ]expr):統計多個記錄中指定字段的值的個數(不計空值)。distinct關鍵字用於去掉重復數據的記錄。
max(expr):統計多個記錄中指定字段的最大值(不計空值)。
min(expr):統計多個記錄中指定字段的最小值(不計空值)。
sum([DISTINCT ]expr):統計多個記錄中指定字段的總和(不計空值)。只適用於數值類型的字段。distinct關鍵字用於去掉重復數據的記錄。
創建
CREATE FUNCTION <函數名>([<參數名> <數據類型>]) RETURNS <數據類型> BEGIN <SQL塊> RETURN <返回值>; END;
需要注意的有:
- MySQL中有一些內置函數,所以自定義函數的函數名不能與內置函數的函數名一致。
- SQL塊中return后的返回值的數據類型必須與returns后定義的數據類型一致。
如果創建時出現以下報錯信息:
解決方法是將全局變量log_bin_trust_function_creators置為ON:
SET @@global.log_bin_trust_function_creators=ON;
調用
SELECT <函數名>([<參數>]);
定義一個可以計算傳入值的平方的函數:
調用函數p:
刪除
DROP FUNCTION <函數名>;