MySQL編程

  MySQL 使用標準 SQL 檢索和處理數據,體積小、開源、免費,易於快速部署。正是由於這些特色,使得其在互聯網行業,特別是 Web 應用方面使用至關普遍。至今最新的版本已到 8.0。html

 

一  基本操做mysql

  MySQL 和 SQL Server 不一樣,它沒有官方的圖形化操做管理軟件,它主要經過命令行的方式操做。sql

  本文主要介紹 MySQL 編程相關的知識,安裝和部署不在本文講解範圍,對於 MySQL 的安裝和部署,請自行查閱官方文檔或其餘資料。數據庫

  

  1,基本命令編程

1 net start mysql80(服務名)
2 net stop mysql80
3 /* 啓動 mysql 服務,不一樣版本的 MySQL 服務名默認不一致,但安裝的時候能夠本身指定 */
4 mysql -h 主機地址 -u 用戶名 -p 用戶密碼
5 /* 登陸 MySQL 服務器,若是是在本地登陸能夠省略主機地址 */
6 exit
7 /* 退出登陸 */

  

  2,基礎語法服務器

  MySQL 採用標準 SQL 語法,他們一樣分爲 DDL、DQL、DML、DCL。編程語言

  詳情能夠移步個人《SQL入門,就這麼簡單》函數

  

  3,註釋oop

  MySQL 使用 # 標記單行註釋,/* */ 標記多行註釋。測試

1 #這是單行註釋
2 /*
3 這是多行註釋
4 */
5 -- 這也是單行註釋

  使用雙橫線註釋時,雙橫線後面至少須要一個空格。

  

  4,語句結束

  因爲 MySQL 使用命令行的方式操做數據庫,因此對於每一條命令,咱們必須明確的指定結束符。MySQL 默認的語句結束符是分號";"。

1 1 語句 1;
2 2 語句 2;
3 3 delimiter $
4 4 /* 經過 delimiter 指定新的結束標識 */
5 5 語句3$
6 6 語句4$

   好比,咱們在建立存儲過程或函數時,函數或存儲過程內部有多條語句,但建立過程自己也是一條語句,爲了不衝突,因此在建立存儲過程和函數時通常會臨時修改語句結束符。不要忘記在建立完後再把結束符改成默認的分號哦。

  

  5,約束

  MySQL 中對約束進行了分類:表約束和列約束,語法稍有差別。

 1 create table myTable(
 2     col1 type[AUTO_INCREMENT],
 3     col2 type,
 4     col3 type,
 5     col4 type,
 6     col5 type NOT NULL,
 7     col6 type DEFAULT 'something',
 8     PRIMARY KEY (col1),
 9     FOREIGN KEY (col2) REFERENCES mytable1(somecol),
10     UNIQUE(col3),
11     CHECK(col4<200)
12 );
13 /*AUTO_INCREMENT 設置主鍵自增,類似的,MsSQL 使用IDENTITY(1,1) 設置自增*/ 

  列約束只有 NOT NULL 和 DEFAULT,其餘的均屬於表約束。

  

  6,查詢相關

  HAVING 關鍵字對聚合後的數據進行再篩選。WHERE 關鍵字是對原始數據的篩選。

1 select a.dep,avg(a.sal) as 平均工資 from salary a
2 left join department b
3 on a.dep=b.dep
4 where b.sta_num>10
5 having avg(sal)>10000;
6 /* 鏈接查詢部門和部門平均工資,部門人數在10以上,且平均工資大於10000 */

  LIMIT 關鍵字,能夠用來返回指定條數的記錄,經常使用來作分頁查詢(MsSQL 使用 top 關鍵字)。limit 須要指定兩個 int 類型的參數,分別表示從哪條記錄開始(第一條數據索引爲0),提取多少條記錄。當從第一條數據開始時,第一個參數能夠省略。

1 /* 基礎用法:返回指定數量記錄 */
2 select * from department order by sta_num limit 10;
3 /* 查詢人數最少的10各部門狀況 */
1 /* 分頁查詢 */
2 SET @num:=10;#定義用戶變量,稍後會詳細講解;每頁須要查詢的記錄數
3 SET @page:=2;#須要查詢第幾頁
4 SET @index=(@page-1)*@num;#開始索引
5 PREPARE mysql FROM "select * from country limit ?,?";#因爲 limit 不支持使用變量,因此必須先使用 prepare 預編譯 SQL 語句,? 標識變量
6 EXECUTE mysql USING @index,@num;#使用 execute 執行預編譯的語句,並使用 using 傳遞參數,順序必須和預編譯時一致

   子查詢又稱嵌套查詢,是指一個 SELECT 語句的查詢結果被嵌套在另外一個語句之中,子查詢既能夠放在 FROM 關鍵字後面,也能夠放在 WHERE 後面。外部的語句能夠是 SELECT、INSERT、DELETE、UPDATE。

1 select * from (
2     selec * from tableA where col1>(
3         select min(col1) from tableB
4     )
5 )a;

 

二  函數

 

  1,字符函數

函數 功能 例子 說明
concat() 鏈接多個字符串 concat('a','b') 鏈接‘a’和‘b’,返回新的字符串‘ab’
substr() 截取字符串 substr('abcde',1,3)  在字符串‘abcde’中從第1個字符開始截取3個字符,並返回
lower()/upper() 字符串大小寫轉換 lower('abD') 把字符串‘abD’都轉換成小寫,並返回
replace() 替換指定字符 replace('abcda','a','x') 把字符串‘abcda’中的‘a’都替換成‘x’,並返回新的字符串
length() 計算字符串長度 length('abcde') 返回字符串‘abcde’的長度
trim() 去掉先後空格 trim('  abc   ') 返回去掉了先後空格的新字符串
lpad()/rpad() 左右填充指定字符 lpad('abc',10,'-') 用‘-’填充字符串‘abc’至長度爲10
instr() 子串第一次出現的索引 instr('abcde','c') 返回在‘abcde’中第一次出現‘c’的索引

  2,數學函數

函數 功能 例子 說明
ceil() 向上取整  ceil(1.1) 2
floor() 向下取整  ceil(1.9) 1
round() 四捨五入  round(2.5) 3
mod() 取模  mod(21,4) 1
truncate() 截斷小數  truncate(1.258,2) 1.25(多餘的小數位直接截斷)
rand() 返回隨機數  rand() 隨機數[0,1)
format() 截斷位數  format(1.258,2) 1.26(最後一位四捨五入得來)

  3,日期函數

函數 功能 例子 說明
now() 返回當前日期時間 now() 2020-05-15 16:27:59
year()/month()/day() 返回年/月/日  year(now())  2020
hour()/minute()/secend() 返回時/分/秒  hour(now())  16
curtime() 返回時間部分  curtime(now())  16:27:59
curdate() 返回日期部分  curdate(now())  2020-05-15
date_format() 格式化日期 date_format(now(),'%Y/%m/%d')  2020/05/15
str_to_date() 把字符串表示的日期轉換成日期格式 str_to_date('2020-05-15 00:00:00','%Y%m%d') 2020/05/15
datediff()  返回兩個日期之間的天數差 datediff(now(),'2020-01-01') 135

  4,聚合函數

函數 功能 例子 說明
max() 返回最大值  max(列名) 返回一列的最大值
min() 返回最小值  min(列名)  返回一列的最小值
avg() 返回平均值  avg(列名)  返回一列的平均值
sum() 返回和  sum(列名)  返回一列的和
count() 返回數量  count(列名)  返回一列的數量(不計算NULL)

  5,其餘函數

    A:IFNULL()

1 /*MySQL*/
2 select IFNULL(NULL,1,2)
3 /*若是第一個參數是 NULL ,則返回第三個參數,不然返回第二個*/
4 /*MsSQL*/
5 select ISNULL(NULL,1)
6 /*若是第一個參數是 NULL,則返回第二個參數,不然原樣返回*/

    B:IF()

1 IF(expr1,expr2,expr3)
2 /*若是 expr1 的值爲 true,則返回 expr2 的值,不然返回 expr3 的值。*/

    C:其餘

1 SELECT DATABASE()
2 SELECT VERSION()
3 SELECT USER()
4 /* 分別返回當前鏈接數據庫,當前數據庫版本,當前用戶 */

 

三   編程對象

 

  1,視圖

    A:建立

1 use world;
2 create view v_1
3 as
4 select * from country limit 10;
5 /* mysql8.0 自帶一個 world 庫*/

    B:刪除

1 drop view v_name;

    C:修改

1 /*方式一:*/
2 alter view v_name
3 as
4     語句;
5 /*方式二:*/
6 create or replace view v_name
7 as
8     語句;

 

  2,變量

  MySQL 中變量分爲 4 種:系統變量,會話變量,用戶變量,局部變量。

    A:系統變量

1 SHOW GLOBAL VARIABLES;
2 /* 查看系統變量。當服務啓動時,它將全部系統變量初始化爲默認值。要想更改全局變量,必須具備super權限。 */

    B:會話變量

1 SHOW SESSION VARIABLES;
2 /* 查看會話變量,只做用於當前鏈接,查看指定系統或會話變量使用:select @@+變量名 */

    C:用戶變量

1 set @name='張三';
2 set @age:=12;
3 select @sex='';
4 select @var:=max(col) from table
5 /* 用戶變量直接賦值便可,使用 select 賦值時只能使用 :=,這是爲了讓系統避免混淆賦值和等於操做,推薦都使用 := */

    D:局部變量

1 1 declare age int default 0;
2 2 set age:=12;
3 3 select @age:=18;
4 4 select max(col) into age from table;
5 5 /* declare 語句專門用於定義局部變量,可使用 default 來指定默認值,直接賦值時,使用 set,則不須要用 @ 標記變量,使用 select 則須要。若是使用查詢賦值,則須要使用 select into.

    局部變量只能在 BENGIN...END 語句塊中使用,好比下面將要講到的存儲過程或函數中。若是如上例中那樣直接運行將報錯。

  

  3,存儲過程

    A:建立

1 create procedure proc_name(參數列表)
2 begin
3     語句塊;
4 end

    參數包含三個部分:參數模式,參數名,參數類型。

    參數模式也分爲三種:IN(僅用來像存儲過程輸入),OUT(僅用來像存儲過程外部輸出),INOUT(便可以用來輸入也能夠用來輸出)。

    存儲過程也能夠沒有參數,括號內留空便可。

    B:調用

1 call proc_name(實參列表);
 1 DELIMITER $ 
 2 CREATE PROCEDURE p_1(IN cname VARCHAR(20),OUT cregion VARCHAR(20))
 3 BEGIN
 4 SELECT region INTO cregion FROM country
 5 WHERE country.name=cname;
 6 END$
 7 /*修改默認結束符後,這種語法只能在命令行模式使用,圖形化界面會報錯(SQLyog,navicat等)
 8 這裏使用的依然是 MySQL8.0 自帶的 world 庫*/
9 CALL('Aruba',@cregion);
10 SELECT @cregion;

    C:刪除

1 drop procedure proc_name;

   存儲過程是一組預編譯的 SQL 語句,使用存儲過程,能夠提升代碼的重用性,簡化操做,由於已經預編譯好了 SQL 代碼,執行時減小了預編譯環節,能夠提升執行效率,通常用來對錶數據進行增刪改。

  

  4,自定義函數

    A:建立

1 DELIMITER $
2 CREATE FUNCTION func_name(參數列表)
3 RETURNS 返回類型
4 BEGIN
5     函數體
6 END$

    函數的參數和存儲過程不一樣,只須要指定參數名和參數類型。而且單獨使用關鍵字 RETURNS 指定返回值類型。因爲函數必須返回值,因此函數內部必須使用 RETURN 關鍵字。RETURN 建議放在函數末尾,由於它會阻斷後面語句的執行。

1 delimiter $
2 create function f_1(num1 float,num2 float)
3 returns float
4 begin
5     declare sum float default 0;
6     set sum:=num1+num2;
7     return sum;
8 end$
9 select f_1(1.1,2.2)$

   MySQL 不支持存儲過程和函數的修改,若是須要修改,必須刪除原來的,並新建同名的過程名或函數名。

1 create percedure|function if not exists name
2 ...
3 /* 建立以前先判斷是否已存在,省得報錯,刪除時也應該檢測是否不存在 */

  

  5,事務

  MySQL 中事務分爲兩類:顯示事務和隱式事務。

  隱式事務不用顯式的指定開始和結束標記。好比 INSERT、UPDATE、DELETE語句都數據隱式事務,他們不須要指定開始和結束,執行就開啓並自動提交。

  顯式事務是指有顯式指定開始和結束標記的事務,這類事務通常由用戶建立。因爲系統默認是開啓了事務自動提交功能的,因此在建立顯式事務時咱們必須先手動的關閉自動提交功能。

1 set autocommit=0;
2 select @@autocommit;
3 /*0爲關閉,1爲開啓,該設置只在本次會話生效*/

   語法:

 1 start transaction;
 2 /*開啓顯式事務*/
 3 語句1;
 4 savepoint point_name;
 5 /*設置事務斷點,不是必須的*/
 6 語句2;
 7 ...
 8 rollback to point_name;
 9 /*回滾到指定斷點,該斷點以前的將不會被回滾*/
10 commit;
11 /*提交事務,全部的操做被提交到數據庫,源數據被修改*/

  若是沒有設置事務斷點,那麼回滾將對全部事務中的語句生效,固然 rollback 後也不須要指定斷點名稱了。提交和回滾不必定會同時存在。

  事務通常是結合應用程序來使用的,直接在 MySQL 中沒法測試。好比,在應用程序中,用戶輸入的信息要被提交到數據庫,當用戶輸入完畢後,點擊提交,咱們能夠設置等待時間,並提示用戶是否確認提交。若是在等待時間結束以後用戶無任何操做,或用戶點擊確認,那麼咱們直接提交事務,若是用戶點擊了取消,那麼咱們能夠回滾事務。

  須要注意的是,MySQL 默認配置了許多不一樣的存儲引擎(又稱表類型),不一樣的存儲引擎使用了不一樣的存儲技術,它們在插入、讀取、修改、事務等方面各有優劣,你能夠爲不一樣的表或庫配置不一樣的存儲引擎。存儲引擎不在本文的講解範圍,這裏專門提到它是想指明另外一個問題:並非全部的 MySQL 存儲引擎都支持事務,只有 InnoDB 引擎支持。因此,若是你但願在 MySQL 中使用事務,請爲其配置 InnoDB 存儲引擎。

 

四  流程控制

 

  1,選擇

    A:CASE 結構

    和其餘編程語言同樣,MySQL 中的 case 語句也是用來實現多分支結構的。不一樣的是,MySQL 中的 case 不只能夠用來作等值判斷,還能夠用來實現相似多重 IF 的邏輯。

    等值判斷:

1 case 表達式或字段
2     when 用來比較的值1 then 返回的值1或語句1;
3     when 用來比較的值2 then 返回的值2或語句2;
4     ...
5     else 返回的值n或語句n;
6 end case;
7 /* case 後面直接跟須要被作等值判斷的表達式或表字段 */

    區間判斷:

1 case
2     when 判斷條件1 then 返回的值1或語句1;
3     when 判斷條件2 then 返回的值2或語句2;
4     ...
5     else 返回的值n或語句n;
6 end case;
7 /* case 後面不跟任何值或表達式,在 when 後經過條件表達式來判斷所屬狀況 */

    若是把 case 結構做爲表達式,那麼它能夠被嵌套在其餘語句中(then 後不須要分號),用在任何地方。若是做爲獨立的語句使用,那麼必須在 begin...end 中。

    B:IF 結構

    IF 結構主要用來實現多重分支的結構,IF 結構只能包含在 BEGIN...END 中使用,不能做爲獨表達式使用,若是想做爲表達式,可使用 IF() 函數,但它只能實現兩個分支。

1 if 判斷條件1
2 then 語句1;
3 elseif 判斷條件2
4 then 語句2;
5 ...
6 else 判斷條件n
7 then 語句n;
8 end if;
9 /* 與其餘編程語言不一樣,這裏的 elseif 中間沒有空格 */

 

  2,循環

    MySQL 中的循環控制語句有兩個:iterate(結束本次循環,執行下一次循環,相似其餘語言中的 continue),leave(結束整個循環,相似 break)。

    另外,循環控制語句必須指明當前退出的是哪一個循環。因此,若是你要使用它們精準控制循環執行,那麼你須要在循環語句最開始指明當前循環的別稱。固然,這不是必須的。

    A:while 循環

1 [循環名稱:]while 循環條件
2 do
3     循環體;
4 end while [循環名稱];
5 /* 經過判斷循環條件來決定是否執行循環體 */

    B:repeat 循環

1 [循環名稱:]repeat
2     循環體;
3 until 循環條件
4 end repeat [循環名稱];
5 /* 先執行一次循環,再檢查循環條件 */ 

    C:loop 循環

1 [循環名稱:]loop
2     循環條件;
3 end loop [循環名稱];
4 /* 沒有循環條件,只能經過循環控制語句結束 */

  MySQL 中的循環語句都只能包含在 begin...end 中使用,因此通常在存儲過程和函數中使用。

相關文章
相關標籤/搜索