MySQL的視圖
?視圖(view)是一個(gè)虛擬表,非真實(shí)存在,其本質(zhì)是根據(jù)SQL語(yǔ)句獲取動(dòng)態(tài)的數(shù)據(jù)集,并為其命名,用戶使用時(shí)只需使用視圖名稱(chēng)即可獲取結(jié)果集,并可以將其當(dāng)作表來(lái)使用。
?數(shù)據(jù)庫(kù)中只存放了視圖的定義,而并沒(méi)有存放視圖中的數(shù)據(jù)。這些數(shù)據(jù)存放在原來(lái)的表中。
?
?使用視圖查詢數(shù)據(jù)時(shí),數(shù)據(jù)庫(kù)系統(tǒng)會(huì)從原來(lái)的表中取出對(duì)應(yīng)的數(shù)據(jù)。因此,視圖中的數(shù)據(jù)是依賴于原來(lái)的表中的數(shù)據(jù)的。一旦表中的數(shù)據(jù)發(fā)生改變,顯示在視圖中的數(shù)據(jù)也會(huì)發(fā)生改變。
作用
?簡(jiǎn)化代碼,可以把重復(fù)使用的查詢封裝成視圖重復(fù)使用,同時(shí)可以使復(fù)雜的查詢易于理解和使用。
?
?安全原因,如果一張表中有很多數(shù)據(jù),很多信息不希望讓所有人看到,此時(shí)可以使用視圖視,如:社會(huì)保險(xiǎn)基金表,可以用視圖只顯示姓名,地址,而不顯示社會(huì)保險(xiǎn)號(hào)和工資數(shù)等,可以對(duì)不同的用戶,設(shè)定不同的視圖。
-- 視圖的創(chuàng)建
create [or replace] [algorithm = {undefined | merge | temptable}]
view view_name [(column_list)]
as select_statement
[with [cascaded | local] check option]
參數(shù)說(shuō)明:
(1)algorithm:可選項(xiàng),表示視圖選擇的算法。
(2)view_name :表示要?jiǎng)?chuàng)建的視圖名稱(chēng)。
(3)column_list:可選項(xiàng),指定視圖中各個(gè)屬性的名詞,默認(rèn)情況下與SELECT語(yǔ)句中的查詢的屬性相同。
(4)select_statement
:表示一個(gè)完整的查詢語(yǔ)句,將查詢記錄導(dǎo)入視圖中。
(5)[with [cascaded | local] check option]:可選項(xiàng),表示更新視圖時(shí)要保證在該視圖的權(quán)限范圍之內(nèi)。
--創(chuàng)建 數(shù)據(jù)庫(kù)mydb6_view,然后在該數(shù)據(jù)庫(kù)下執(zhí)行sql腳本view_data.sql 導(dǎo)入數(shù)據(jù)
create database mydb6_view;
create or replace view view1_emp
as
select ename,job from emp;
-- 查看表和視圖
show full tables;
-- 修改視圖:修改視圖是指修改數(shù)據(jù)庫(kù)中已存在的表的定義。當(dāng)基本表的某些字段發(fā)生改變時(shí),可以通過(guò)修改視圖來(lái)保持視圖和基本表之間一致。MySQL中通過(guò)CREATE OR REPLACE VIEW語(yǔ)句和ALTER VIEW語(yǔ)句來(lái)修改視圖。
alter view 視圖名 as select語(yǔ)句
alter view view1_emp
as
select a.deptno,a.dname,a.loc,b.ename,b.sal from dept a, emp b where a.deptno = b.deptno;
-- 更新視圖
create or replace view view1_emp
as
select ename,job from emp;
update view1_emp set ename = '周瑜' where ename = '魯肅'; -- 可以修改
insert into view1_emp values('孫權(quán)','文員'); -- 不可以插入
-- ----------視圖包含聚合函數(shù)不可更新--------------
create or replace view view2_emp
as
select count(*) cnt from emp;
insert into view2_emp values(100);
update view2_emp set cnt = 100;
-- ----------視圖包含distinct不可更新---------
create or replace view view3_emp
as
select distinct job from emp;
insert into view3_emp values('財(cái)務(wù)');
-- ----------視圖包含goup by 、having不可更新------------------
create or replace view view4_emp
as
select deptno ,count(*) cnt from emp group by deptno having cnt > 2;
insert into view4_emp values(30,100);
-- ----------------視圖包含union或者union all不可更新----------------
create or replace view view5_emp
as
select empno,ename from emp where empno <= 1005
union
select empno,ename from emp where empno > 1005;
insert into view5_emp values(1015,'韋小寶');

-- -------------------視圖包含子查詢不可更新--------------------
create or replace view view6_emp
as
select empno,ename,sal from emp where sal = (select max(sal) from emp);
insert into view6_emp values(1015,'韋小寶',30000);
-- ----------------------視圖包含join不可更新-----------------
create or replace view view7_emp
as
select dname,ename,sal from emp a join dept b on a.deptno = b.deptno;
insert into view7_emp(dname,ename,sal) values('行政部','韋小寶',30000);
-- --------------------視圖包含常量文字值不可更新-------------------
create or replace view view8_emp
as
select '行政部' dname,'楊過(guò)' ename;
insert into view8_emp values('行政部','韋小寶');
--重命名視圖
-- rename table 視圖名 to 新視圖名;
rename table view1_emp to my_view1
-- 刪除視圖 刪除視圖時(shí),只能刪除視圖的定義,不會(huì)刪除數(shù)據(jù)
-- drop view 視圖名[,視圖名…];
drop view if exists view_student;
Mysql的存儲(chǔ)過(guò)程
什么是存儲(chǔ)過(guò)程
?.0 版本開(kāi)始支持存儲(chǔ)過(guò)程。
?
?簡(jiǎn)單的說(shuō),存儲(chǔ)過(guò)程就是一組SQL語(yǔ)句集,功能強(qiáng)大,可以實(shí)現(xiàn)一些比較復(fù)雜的邏輯功能,類(lèi)似于JAVA語(yǔ)言中的方法;
?
存儲(chǔ)過(guò)就是數(shù)據(jù)庫(kù)SQL語(yǔ)言層面的代碼封裝與重用
有哪些特性
?有輸入輸出參數(shù),可以聲明變量,有if/else, case,while等控制語(yǔ)句,通過(guò)編寫(xiě)存儲(chǔ)過(guò)程,可以實(shí)現(xiàn)復(fù)雜的邏輯功能;
?
?函數(shù)的普遍特性:模塊化,封裝,代碼復(fù)用;
?
?速度快,只有首次執(zhí)行需經(jīng)過(guò)編譯和優(yōu)化步驟,后續(xù)被調(diào)用可以直接執(zhí)行存儲(chǔ)過(guò)程執(zhí)行動(dòng)態(tài)查詢,省去以上步驟;
delimiter 自定義結(jié)束符號(hào)
create procedure 儲(chǔ)存名([ in ,out ,inout ] 參數(shù)名 數(shù)據(jù)類(lèi)形...)
begin
sql語(yǔ)句
end 自定義的結(jié)束符合
delimiter ;
-- 1:創(chuàng)建數(shù)據(jù)庫(kù)
create database mydb7_procedure;
-- 2:在該數(shù)據(jù)庫(kù)下導(dǎo)入sql腳本:procedure_data.sql
-- 創(chuàng)建存儲(chǔ)過(guò)程
delimiter $$
create procedure proc01()
begin
select empno,ename from emp;
end $$
delimiter ;
-- 調(diào)用存儲(chǔ)過(guò)程
call proc01();
-- 局部變量 用戶自定義 在begin/end塊中有效
語(yǔ)法: 聲明變量 declare var_name type [default var_value];
舉例:declare nickname varchar(32);
delimiter $$
create procedure proc02()
begin
declare var_name01 varchar(20) default ‘a(chǎn)aa’; -- 定義局部變量
set var_name01 = ‘zhangsan’;
select var_name01;
end $$
delimiter ;
-- 調(diào)用存儲(chǔ)過(guò)程
call proc02();
-- mysql中還可以使用select init 語(yǔ)句為變量賦值 語(yǔ)法
select col_name [...] into var_name[,...]

from table_name wehre condition
其中:
col_name 參數(shù)表示查詢的字段名稱(chēng);
var_name 參數(shù)是變量的名稱(chēng);
table_name 參數(shù)指表的名稱(chēng);
condition 參數(shù)指查詢條件。
注意:當(dāng)將查詢結(jié)果賦值給變量時(shí),該查詢語(yǔ)句的返回結(jié)果只能是單行單列。
delimiter $$
create procedure proc03()
begin
declare my_ename varchar(20) ;
select ename into my_ename from emp where empno=1001;
select my_ename;
end $$
delimiter ;
-- 調(diào)用存儲(chǔ)過(guò)程
call proc03();
-- 用戶自定義,當(dāng)前會(huì)話(連接)有效。類(lèi)比java的成員變量
delimiter $$
create procedure proc04()
begin
set @var_name01 = 'ZS';
end $$
delimiter;
call proc04() ;
select @var_name01 ; --可以看到結(jié)果
-- 全局變量 語(yǔ)法:
@@global.var_name
-- 查看全局變量
show global variables;
-- 查看某全局變量
select @@global.auto_increment_increment;
-- 修改全局變量的值
set global sort_buffer_size = 40000;
set @@global.sort_buffer_size = 40000;
-- 變量定義 語(yǔ)法
@@session.var_name
-- 查看會(huì)話變量
show session variables;
-- 查看某會(huì)話變量
select @@session.auto_increment_increment;
-- 修改會(huì)話變量的值
set session sort_buffer_size = 50000;
set @@session.sort_buffer_size = 50000 ;
存儲(chǔ)過(guò)程傳參 in out inout
-- 存儲(chǔ)過(guò)程傳參-in
-- 封裝有參數(shù)的存儲(chǔ)過(guò)程,傳入員工編號(hào),查找員工信息
delimiter $$
create procedure dec_param01(in param_empno varchar(20))
begin
select * from emp where empno = param_empno;
end $$
delimiter ;
call dec_param01('1001');
-- 封裝有參數(shù)的存儲(chǔ)過(guò)程,可以通過(guò)傳入部門(mén)名和薪資,查詢指定部門(mén),并且薪資大于指定值的員工信息
delimiter $$
create procedure dec_param0x(in dname varchar(50),in sal decimal(7,2),)
begin
select * from dept a, emp b where b.sal > sal and a.dname = dname;
end $$
delimiter ;
call dec_param0x('學(xué)工部',20000);
-- 存儲(chǔ)過(guò)程傳參- out
use mysql7_procedure;
-- 封裝有參數(shù)的存儲(chǔ)過(guò)程,傳入員工編號(hào),返回員工名字
delimiter $$
create procedure proc08(in empno int ,out out_ename varchar(50) )
begin
select ename into out_ename from emp where emp.empno = empno;

end $$
delimiter ;
call proc08(1001, @o_ename);
select @o_ename;
-- 封裝有參數(shù)的存儲(chǔ)過(guò)程,傳入員工編號(hào),返回員工名字和薪資
delimiter $$
create procedure proc09(in empno int ,out out_ename varchar(50) ,out out_sal decimal(7,2))
begin
select ename,sal into out_ename,out_sal from emp where emp.empno = empno;
end $$
delimiter ;
call proc09(1001, @o_dname,@o_sal);
select @o_dname;
select @o_sal;
-- 存儲(chǔ)過(guò)程傳參 inout
-- 傳入員工名,拼接部門(mén)號(hào),傳入薪資,求出年薪
delimiter $$
create procedure proc10(inout inout_ename varchar(50),inout inout_sal int)
begin
select concat(deptno,"_",inout_ename) into inout_ename from emp where ename = inout_ename;
set inout_sal = inout_sal * 12;
end $$
delimiter ;
set @inout_ename = '關(guān)羽';
set @inout_sal = 3000;
call proc10(@inout_ename, @inout_sal) ;
select @inout_ename ;
select @inout_sal ;
存儲(chǔ)過(guò)程流程控制
-- 流程控制-判斷IF語(yǔ)句包含多個(gè)條件判斷,根據(jù)結(jié)果為T(mén)RUE、FALSE執(zhí)行語(yǔ)句,與編程語(yǔ)言中的if、else if、else語(yǔ)法類(lèi)似,其語(yǔ)法格式如下:
-- 語(yǔ)法
if search_condition_1 then statement_list_1
[elseif search_condition_2 then statement_list_2] ...
[else statement_list_n]
end if
-- 輸入學(xué)生的成績(jī),來(lái)判斷成績(jī)的級(jí)別:
/*
score < 60 :不及格
score >= 60 , score <80 :及格
score >= 80 , score < 90 :良好
score >= 90 , score <= 100 :優(yōu)秀
score > 100 :成績(jī)錯(cuò)誤
*/
delimiter $$
create procedure proc_12_if(in score int)
begin
if score < 60
then
select '不及格';
elseif score < 80
then
select '及格' ;
elseif score >= 80 and score < 90
then
select '良好';
elseif score >= 90 and score <= 100
then
select '優(yōu)秀';
else
select '成績(jī)錯(cuò)誤';
end if;
end $$
delimiter ;
call proc_12_if(120)
-- 流程控制- case CASE是另一個(gè)條件判-- 語(yǔ)法一(類(lèi)比java的switch):
case case_value
when when_value then statement_list
[when when_value then statement_list] ...
[else statement_list]
end case
-- 語(yǔ)法二:

case
when search_condition then statement_list
[when search_condition then statement_list] ...
[else statement_list]
end case
斷的語(yǔ)句,類(lèi)似于編程語(yǔ)言中的switch語(yǔ)法
-- 語(yǔ)法一
delimiter $$
create procedure proc14_case(in pay_type int)
begin
case pay_type
when 1
then
select '微信支付' ;
when 2 then select '支付寶支付' ;
when 3 then select '銀行卡支付';
else select '其他方式支付';
end case ;
end $$
delimiter ;
call proc14_case(2);
call proc14_case(4);
流程控制-循壞
?循環(huán)是一段在程序中只出現(xiàn)一次,但可能會(huì)連續(xù)運(yùn)行多次的代碼。
?循環(huán)中的代碼會(huì)運(yùn)行特定的次數(shù),或者是運(yùn)行到特定條件成立時(shí)結(jié)束循環(huán)
循環(huán)分類(lèi):
?while
?
?loop
循環(huán)控制:
?leave類(lèi)似于 break,跳出,結(jié)束當(dāng)前所在的循環(huán)
?類(lèi)似于 ,繼續(xù)存儲(chǔ)過(guò)程執(zhí)行動(dòng)態(tài)查詢,結(jié)束本次循環(huán),繼續(xù)下一次
-- 流程控制- 循壞 -while
【標(biāo)簽:】while 循環(huán)條件 do
循環(huán)體;
end while【 標(biāo)簽】;
-- 創(chuàng)建測(cè)試表
create table user (
uid int primary_key,
username varchar ( 50 ),
password varchar ( 50 )
);
-- 操作
-- -------存儲(chǔ)過(guò)程-while
delimiter $$
create procedure proc16_while1(in insertcount int)
begin
declare i int default 1;
label:while i<=insertcount do
insert into user(uid,username,`password`) values(i,concat('user-',i),'123456');
set i=i+1;
end while label;
end $$
delimiter ;
call proc16_while(10);
-- 流程控制 -混懷 -repeat 格式
[標(biāo)簽:]repeat
循環(huán)體;
until 條件表達(dá)式
end repeat [標(biāo)簽];
-- -------存儲(chǔ)過(guò)程-循環(huán)控制-repeat
use mysql7_procedure;
truncate table user;
delimiter $$
create procedure proc18_repeat(in insertCount int)
begin
declare i int default 1;
label:repeat
insert into user(uid, username, password) values(i,concat('user-',i),'123456');

set i = i + 1;
until i > insertCount
end repeat label;
select '循環(huán)結(jié)束';
end $$
delimiter ;
call proc18_repeat(100);
流程控制-循壞 -loop 語(yǔ)法
[標(biāo)簽:] loop
循環(huán)體;
if 條件表達(dá)式 then
leave [標(biāo)簽];
end if;
end loop;
-- -------存儲(chǔ)過(guò)程-循環(huán)控制-loop
truncate table user;
delimiter $$
create procedure proc19_loop(in insertCount int)
begin
declare i int default 1;
label:loop
insert into user(uid, username, password) values(i,concat('user-',i),'123456');
set i = i + 1;
if i > 5
then
leave label;
end if;
end loop label;
select '循環(huán)結(jié)束';
end $$
delimiter ;
call proc19_loop(10);
存儲(chǔ)過(guò)程-游標(biāo)
-- 聲明語(yǔ)法
declare cursor_name cursor for select_statement
-- 打開(kāi)語(yǔ)法
open cursor_name
-- 取值語(yǔ)法
fetch cursor_name into var_name [, var_name] ...
-- 關(guān)閉語(yǔ)法
close cursor_name
-- 操作
use mysql7_procedure;
delimiter $$
create procedure proc20_cursor(in in_dname varchar(50))
begin
-- 定義局部變量
declare var_empno varchar(50);
declare var_ename varchar(50);
declare var_sal decimal(7,2);
-- 聲明游標(biāo)
declare my_cursor cursor for
select empno , ename, sal
from dept a ,emp b
where a.deptno = b.deptno and a.dname = in_dname;
-- 打開(kāi)游標(biāo)
open my_cursor;
-- 通過(guò)游標(biāo)獲取每一行數(shù)據(jù)
label:loop
fetch my_cursor into var_empno, var_ename, var_sal;
select var_empno, var_ename, var_sal;
end loop label;
-- 關(guān)閉游標(biāo)
close my_cursor;
end
-- 調(diào)用存儲(chǔ)過(guò)程
call proc20_cursor('銷(xiāo)售部');