MySQL快速入門13----SQL編程

SQL:結構化查詢語言,是一門編程語言,是一種管理數據的編程語言!




一 元素


數據、數據類型、變量、函數、控制流程、運算符 、註釋。。。

二 註釋


行註釋:

方法一: #
首先表one中的內容爲:
mysql> select * from one;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)

當id爲1時的表one的內容:
mysql> select * from one where one_id = 1;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
+--------+----------+--------------+
1 row in set (0.00 sec)

加註釋的時候:
mysql> select * from one #where one_id = 1;
    -> ;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)

方法二:--【空格】

mysql> select * from one -- where one_id = 1;
    -> ;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)

塊註釋:


/* */
mysql> select * from one /* where id = 1;*/;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)


三 結束符


分號、\G、\g

其中分號和\g是一樣的;

\G會對輸出結果進行優化;

mysql> select * from one \G;
*************************** 1. row ***************************
      one_id: 1
    one_data: A
public_field: 222
*************************** 2. row ***************************
      one_id: 2
    one_data: B
public_field: 20
*************************** 3. row ***************************
      one_id: 3
    one_data: X
public_field: 30
3 rows in set (0.00 sec)

可以使用delimiter來修改結束符;
mysql> delimiter $$
mysql> select * from one$$
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)

mysql> delimiter ;


四 變量




MySQL中,允許用戶自己定義變量。即爲用戶變量(用戶自定義變量)。

語法:
Set 語句可以定義併爲變量賦值。
Set @var = value;

也可以使用select into 語句。爲變量初始化並賦值。這樣要求select語句只能返回一行,但是可以是多個字段,就意味着同時爲多個變量進行賦值,變量的數量需要與查詢的列數一致。

還可以把賦值語句看作一個表達式,通過select 執行完成。此時爲了避免=被當作關係運算符看待,使用:=代替。(set語句可以使用= 和 :=)。
Select @var:=20; 
Select @v1:=id, @v2=name from t1 limit 1;
select * from tbl_name where @var:=30;

自定義變量名:
爲了避免select語句中
避免用戶自定義的變量與系統標識符(通常是字段名),用戶自定義變量在變量名前使用@作爲開始符號。
@var=10;

變量被定義後,在整個會話週期都有效(登錄到退出)


系統中有許多默認的變量,如:
mysql> show variables like 'char%';
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | gbk                                    |
| character_set_connection | gbk                                    |
| character_set_database   | utf8                                   |
| character_set_filesystem | binary                                 |
| character_set_results    | gbk                                    |
| character_set_server     | utf8                                   |
| character_set_system     | utf8                                   |
| character_sets_dir       | D:\Program_win10\MySQL\share\charsets\ |
+--------------------------+----------------------------------------+
8 rows in set (0.00 sec)

定義一個變量:
set 變量名 = 變量值
注意,爲了區分 系統變量和字段與用戶自定義變量,需要在用戶變量前,增加@標識符。

mysql> set @v1 = 123;
Query OK, 0 rows affected (0.00 sec)

mysql> select @v1;
+------+
| @v1  |
+------+
|  123 |
+------+
1 row in set (0.00 sec)
通過 select 語句可以獲得當前的變量的值。


Set是專門的爲變量賦值的形式,甚至可以子查詢:
mysql> set @v2 = (select public_field from one where one_id = 1);
Query OK, 0 rows affected (0.00 sec)

mysql> select @v2;
+------+
| @v2  |
+------+
|  222 |
+------+
1 row in set (0.00 sec)

使用select into注入多個變量:
mysql> select 1,2,3 into @v3, @v4,@v5;
Query OK, 1 row affected (0.00 sec)

mysql> select @v3,@b4,@v5;
+------+------+------+
| @v3  | @b4  | @v5  |
+------+------+------+
|    1 | NULL |    3 |
+------+------+------+
1 row in set (0.00 sec)

mysql> select public_field from one where one_id = 1 into @v6;
Query OK, 1 row affected (0.00 sec)

mysql> select @v6;
+------+
| @v6  |
+------+
|  222 |
+------+
1 row in set (0.00 sec)

注意:select into @var 要求,只能返回一行。如果返回多行,會語法錯誤,或者只將最後一行的數據,注入到變量內。

使用select 爲變量賦值的時候使用 :=(如果直接使用等號的話,相當於判斷語句了!!!)
mysql> select @v7:='Apple';
+--------------+
| @v7:='Apple' |
+--------------+
| Apple        |
+--------------+
1 row in set (0.00 sec)

mysql> select @v7;
+-------+
| @v7   |
+-------+
| Apple |
+-------+
1 row in set (0.00 sec)

比較一下語句的區別:
mysql> select * from one where @v3 = one_id;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
+--------+----------+--------------+
1 row in set (0.00 sec)

mysql> select * from one where @v3 := one_id;
+--------+----------+--------------+
| one_id | one_data | public_field |
+--------+----------+--------------+
|      1 | A        |          222 |
|      2 | B        |           20 |
|      3 | X        |           30 |
+--------+----------+--------------+
3 rows in set (0.00 sec)


1,作用域。用戶定義的函數,是全局的(函數內可用)。存在局部作用域變量,函數內定義的變量。
2,有效期。會話結束(連接結束)。


五 函數





5.1 內置函數




數值函數

Abs(X),絕對值 abs(-10.9) = 10
Format(X,D),格式化千分位數值 format(1234567.456, 2) = 1,234,567.46
Ceil(X),向上取整 ceil(10.1) = 11
Floor(X),向下取整 floor (10.1) = 10
Round(X),四捨五入去整
Mod(M,N) M%N M MOD N 求餘 10%3=1
Pi(),獲得圓周率
Pow(M,N) M^N
Sqrt(X),算術平方根
Rand(),隨機數
TRUNCATE(X,D) 截取D位小數


時間日期函數

Now(),current_timestamp(); 當前日期時間
Current_date();當前日期
current_time();當前時間
Date(‘yyyy-mm-dd HH;ii:ss’);獲取日期部分
Time(‘yyyy-mm-dd HH;ii:ss’);獲取時間部分
Date_format(‘yyyy-mm-dd HH;ii:ss’,’ %D %y %a %d %m %b %j');
Unix_timestamp();獲得unix時間戳
From_unixtime();//從時間戳獲得時間


字符串函數

LENGTH (string ) //string長度,字節
CHAR_LENGTH(string) //string的字符個數
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
INSTR (string ,substring ) //返回substring首次在string中出現的位置
CONCAT (string [,... ]) //連接字串
CHARSET(str) //返回字串字符集
LCASE (string ) //轉換成小寫
LEFT (string ,length ) //從string2中的左邊起取length個字符
LOAD_FILE (file_name ) //從文件讀取內容
LOCATE (substring , string [,start_position ] ) //同INSTR,但可指定開始位置
LPAD (string ,length ,pad ) //重複用pad加在string開頭,直到字串長度爲length
LTRIM (string ) //去除前端空格
REPEAT (string ,count ) //重複count次
RPAD (string ,length ,pad) //在str後用pad補充,直到長度爲length
RTRIM (string ) //去除後端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小


流程函數:

CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END 多分支
IF(expr1,expr2,expr3) 雙分支。


聚合函數

Count()
Sum();
Max();
Min();
Avg();
Group_concat()


其他常用函數

Md5();
Default();


內置函數舉例:


rand返回0到1的隨機數:
mysql> select rand();
+--------------------+
| rand()             |
+--------------------+
| 0.8635645637880681 |
+--------------------+
1 row in set (0.03 sec)

如何得到5到10之間的隨機數呢?
mysql> select floor(rand()*5 + 5);
+---------------------+
| floor(rand()*5 + 5) |
+---------------------+
|                   8 |
+---------------------+
1 row in set (0.00 sec)

mysql> select floor(rand()*5 + 5);
+---------------------+
| floor(rand()*5 + 5) |
+---------------------+
|                   5 |
+---------------------+
1 row in set (0.00 sec)

now()函數:
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2016-08-09 00:14:53 |
+---------------------+
1 row in set (0.02 sec)

unix_timestamp函數:
mysql> select unix_timestamp();
+------------------+
| unix_timestamp() |
+------------------+
|       1470672909 |
+------------------+
1 row in set (0.00 sec)

獲取當前時間:
mysql> select now(unix_timestamp());
+-----------------------+
| now(unix_timestamp()) |
+-----------------------+
| 2016-08-09 00:15:32   |
+-----------------------+
1 row in set (0.00 sec)

字符串,substring(原字符串,開始位置,截取長度),位置從1開始:
mysql> select substring('Apple', 1, 2);
+--------------------------+
| substring('Apple', 1, 2) |
+--------------------------+
| Ap                       |
+--------------------------+
1 row in set (0.00 sec)

length函數(別忘了設置set names gbk;):
mysql> select length('Apple'), length('蘋果');
+-----------------+----------------+
| length('Apple') | length('蘋果')    |
+-----------------+----------------+
|               5 |              4 |
+-----------------+----------------+
1 row in set (0.01 sec)

lpad(需要補足的字符串,補足後的長度,補字符串):
mysql> select lpad('abc', 5, '5');
+---------------------+
| lpad('abc', 5, '5') |
+---------------------+
| 55abc               |
+---------------------+
1 row in set (0.00 sec)

六 存儲函數----自定義函數




6.1 要素


函數名
參數列表
函數體
返回值

6.2 語法


Create function function_name (參數列表) returns 返回值類型
函數體

函數名,應該合法的標識符,並且不應該與已有的關鍵字衝突。

一個函數應該屬於某個數據庫,可以使用db_name.funciton_name的形式執行當前函數所屬數據庫,否則爲當前數據庫。


參數部分,由參數名和參數類型組成。

返回值類類型

函數體由多條可用的mysql語句,流程控制,變量聲明等語句構成。

多條語句應該使用 begin end語句塊包含。

注意,一定要有return 返回值語句。

刪除:
Drop function if exists function_name;

查看:
Show function status like ‘partten’
Show create function function_name;

修改:
Alter function function_name 函數選項。




創建函數,功能時返回hello,world!:
mysql> delimiter $$
mysql> create function sayHello() returns varchar(20)
    -> begin
    ->  return 'hello, world!';
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

函數執行結果:
mysql> select sayHello();
+---------------+
| sayHello()    |
+---------------+
| hello, world! |
+---------------+
1 row in set (0.02 sec)

注意:函數是與當前的數據庫綁定的,可以使用庫名.函數名的形式調用;

6.3 sql中的流程控制


分支語句


If 條件1 then
<span style="white-space:pre">	</span>條件1滿足執行的語句
Elseif 條件2 then
<span style="white-space:pre">	</span>條件2滿足執行的語句
….
Else 
<span style="white-space:pre">	</span>上面的條件全都不滿足,執行的語句
End if;
其中,Elseif 和 else 都是可以省略的。

mysql> delimiter $$
mysql> create function fun1() returns varchar(20)
    -> begin
    ->  if hour(now())<12 then
    ->          return '早上好!';
    ->  elseif hour(now())<18 then
    ->          return '下午好!';
    ->  else
    ->          return '晚上好!';
    ->  end if;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> select fun1() as 打招呼;
+----------+
| 打招呼        |
+----------+
| 下午好!        |
+----------+
1 row in set (0.00 sec)

循環語句


While 條件 do
循環體
End while;

mysql> delimiter $$
mysql> drop function if exists fun2;
    -> create function fun2() returns int
    -> begin
    ->  set @i = 0; -- 全局變量
    ->  set @total = 0;-- 全局變量
    ->  while @i<10 do
    ->          set @i = @i+1;
    ->          set @total = @total + @i;
    ->  end while;
    ->
    ->  return @total;
    -> end
    -> $$
Query OK, 0 rows affected (0.08 sec)

Query OK, 0 rows affected (0.09 sec)

mysql> delimiter ;
mysql> select fun2();
+--------+
| fun2() |
+--------+
|     55 |
+--------+
1 row in set (0.00 sec)

帶形參的函數:
mysql> delimiter $$
mysql> drop function if exists fun2;
    -> create function fun3(n int) returns int
    -> begin
    ->  set @i = 0; -- 全局變量
    ->  set @total = 0;-- 全局變量
    ->  while @i<n do
    ->          set @i = @i+1;
    ->          set @total = @total + @i;
    ->  end while;
    ->
    ->  return @total;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> select fun3(10);
+----------+
| fun3(10) |
+----------+
|       55 |
+----------+
1 row in set (0.00 sec)


循環的提前終止:
leave 終止當前循環,即跳出循環;
iterate 跳過本次循環,進入下一次循環,注意變量的增量;


循環的標籤,給循環起名字(便於指定跳過哪個循環):
標籤:while
end while 標籤;

跳出循環的例子:
mysql> delimiter $$
mysql> drop function if exists fun2;
    -> create function fun5(n int) returns int
    -> begin
    ->  set @i = 0; -- 全局變量
    ->  set @total = 0;-- 全局變量
    ->  w:while @i<n do
    ->          if @i= 5 then
    ->                  leave w;
    ->          end if;
    ->          set @i = @i+1;
    ->          set @total = @total + @i;
    ->  end while w;
    ->
    ->  return @total;
    -> end
    -> $$
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> select fun5(10);
+----------+
| fun5(10) |
+----------+
|       15 |
+----------+
1 row in set (0.02 sec)


跳過某次循環的例子:
mysql> delimiter $$
mysql> create function fun6(n int) returns int
    -> begin
    ->  set @i = 0; -- 全局變量
    ->  set @total = 0;-- 全局變量
    ->  w:while @i<n do
    ->          if @i= 5 then
    ->                  set @i = @i+1;
    ->                  iterate w;
    ->          end if;
    ->          set @i = @i+1;
    ->          set @total = @total + @i;
    ->  end while w;
    ->
    ->  return @total;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> select fun6(10);
+----------+
| fun6(10) |
+----------+
|       49 |
+----------+
1 row in set (0.00 sec)


6.4 函數內使用的變量


@var的形式,相當於全局變量,函數內和函數外是通用的。






DECLARE var_name[,...] type [DEFAULT value] 
這個語句被用來聲明局部變量。要給變量提供一個默認值,請包含一個DEFAULT子句。值可以被指定爲一個表達式,不需要爲一個常數。如果沒有DEFAULT子句,初始值爲NULL。 

mysql> delimiter $$
mysql> create function fun7(n int) returns int
    -> begin
    ->  declare i int default 0; -- 局部變量
    ->  declare total int default 0;-- 局部變量
    ->  w:while i<n do
    ->          if i= 5 then
    ->                  set i = @i+1;
    ->                  iterate w;
    ->          end if;
    ->          set i = i+1;
    ->          set total = total + i;
    ->  end while w;
    ->
    ->  return total;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> select fun7(10);
+----------+
| fun7(10) |
+----------+
|       15 |
+----------+
1 row in set (0.00 sec)





例子:隨機獲取姓名
mysql> -- 參考學生表
mysql> create table join_student (
    -> stu_id int not null auto_increment,
    -> stu_no char(10),
    -> class_id int not null,
    -> stu_name varchar(10),
    -> stu_info text,
    -> primary key (stu_id)
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql>
mysql> -- 計算新增學號
mysql> drop function if exists sno;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> delimiter $$
mysql> create function sno (c_id int) returns char(10)
    -> begin
    -> declare last_no char(10);
    -> select stu_no from join_student where class_id=c_id order by stu_no desc limit 1 into last_no;
    -> if last_no is null then
    ->     return concat((select c_name from join_class where id=c_id), '001');
    -> else
    ->     return concat(left(last_no, 7), lpad(right(last_no, 3) + 1, 3, '0'));
    -> end if;
    -> #return @last_no;
    -> end
    -> $$
Query OK, 0 rows affected (0.02 sec)

mysql> delimiter ;
mysql> -- 隨機獲得學生名字。
mysql> drop function if exists sname;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> delimiter $$
mysql> create function sname () returns char(2)
    -> begin
    -> declare first_name char(16) default '趙錢孫李周吳鄭王馮陳褚衛蔣沈韓楊';
    -> declare last_name char(10) default '甲乙丙丁戊己庚辛壬癸';
    -> declare full_name char(2);
    -> set full_name = concat(substring(first_name, floor(rand()*16+1), 1), substring(last_name, floor(rand()*10+1), 1));
    -> return full_name;
    -> end
    -> $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql>
mysql> select sname();
+---------+
| sname() |
+---------+
| 韓甲        |
+---------+
1 row in set (0.00 sec)

mysql> select sname();
+---------+
| sname() |
+---------+
| 陳庚       |
+---------+
1 row in set (0.00 sec)

mysql> select sname();
+---------+
| sname() |
+---------+
| 馮庚        |
+---------+
1 row in set (0.00 sec)

mysql> select sname();
+---------+
| sname() |
+---------+
| 蔣壬        |
+---------+
1 row in set (0.00 sec)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章