1. 程式人生 > >資料庫學習--mySQL

資料庫學習--mySQL

此文針對資料庫database:crashbase,包含如下表

  1. customers:客戶資訊
    cust_id cust_name cust_address cust_city cust_state cust_country cust_contact cust_email
  2. orderitems:每種商品的訂單資訊
    order_num order_item prod_id quantity item_price
  3. orders,每個客戶的訂單
    order_num order_date cust_id
  4. productnotes,每種商品的備註
    note_id prod_id note_date prod_text
  5. products,每種產品的進售資訊
    prod_id vend_id prod_name prod_price prod_desc
  6. vendors,所有的供應商
    vend_id vend_name vend_address vend_city vend_state vend_zip vend_country

orders儲存實際的訂單,而orderitems儲存訂購的各項物品。
這兩個表使用稱為主鍵(參閱第1章)的唯一ID互相關聯。
這兩個表又與包含客戶和產品資訊的其他表相關聯。

一般關鍵字用大寫,表名,行列名用小寫 

show tables;#顯示當前資料庫中所有的表
use world;#啟用另一個數據庫
show columns from customers;#顯示列
describe customers;#
show status;#用於顯示廣泛的伺服器狀態資訊;
show grants;#用來顯示授予使用者(所有使用者或特定使用者)的安全許可權
show errors;#
show warnings;#用來顯示伺服器錯誤或警告訊息

#第五章:排序檢索資料,SELECT,ORDER BY,DESC, LIMIT(限制行數)
select prod_name from products;
SELECT prod_id,prod_name,prod_price FROM products;#選擇多列並顯示
SELECT * FROM products;#*代表所有
SELECT DISTINCT vend_id from products;#DISTINCT:不重複
SELECT prod_name FROM products ORDER BY prod_name;#ORDER BY排序
SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price, prod_name;
SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC, prod_name;#降序
SELECT prod_price FROM products ORDER BY prod_price DESC LIMIT 1;#最高價格,LIMIT 1限制第一行
SELECT prod_id, prod_price FROM products ORDER BY prod_price DESC LIMIT 1;
#note:ORDER BY必須是SELECT語句中的最後一條子句,可根據需要對一個或多個列進行排序

#第六章:過濾資料 SELECT + WHERE
SELECT prod_id, prod_price FROM products WHERE prod_price = 2.5;
SELECT prod_name, prod_price FROM products WHERE prod_name = 'fuses';#匹配時不區分大小寫
SELECT prod_name, prod_price FROM products WHERE prod_price<=10;
SELECT prod_name, prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;#範圍篩選·
SELECT prod_name,prod_price FROM products WHERE prod_price = NULL;#NULL檢索空值

#第七章:過濾資料 WHERE子句的組合:AND OR
SELECT vend_id, prod_id, prod_name,prod_price FROM products 
WHERE vend_id = 1003 AND prod_price <=10 
ORDER BY prod_price DESC;#並且排了序,OR類似
#注意OR優先順序大於AND,一塊兒使用時要加小括號
SELECT prod_name, vend_id, prod_price FROM products
WHERE (vend_id = 1002 OR vend_id  = 1003) AND prod_price <= 10
ORDER BY prod_price DESC;
#IN代替WHERE(推薦,速度更快,更簡潔,最大優點:可以包含其他SELECT語句,動態的建立WHERE子句):指定條件範圍
SELECT vend_id, prod_id, prod_name, prod_price FROM products
WHERE vend_id IN(1002,1003)
ORDER BY prod_price DESC;
SELECT vend_id, prod_id, prod_name, prod_price FROM products
WHERE vend_id NOT IN(1002,1003)
ORDER BY prod_price DESC;#NOT否定任何條件

#第八章:用萬用字元(用來匹配值的一部分的特殊字元)過濾 LIKE:% _
#搜尋模式:由字面值、萬用字元或者兩者組合構成的搜尋條件,和正則表示式不同:LIKE匹配整個列
SELECT prod_id,prod_name FROM products
WHERE prod_name LIKE 'jet%'; #以jet開頭
select prod_id,prod_name,prod_price FROM products
WHERE prod_price LIKE 10;#這樣匹配數字是錯誤的
SELECT prod_id, prod_name FROM products
WHERE prod_name LIKE '%anvil%';#匹配anvil
#note:%不能匹配NULL,_類似LIKE但是_只能匹配一個字元

#第九章:用正則表示式進行搜尋(匹配文字的特殊的串,字元集合)  REGEXP
SELECT prod_name FROM products
WHERE prod_name REGEXP '1000'
ORDER BY prod_name DESC;

SELECT prod_name FROM products
WHERE prod_name REGEXP '.000'# .表示匹配任意一個字元,將返回1000,2000
ORDER BY prod_name;

#正則表示式重複元字元:
/*
* 0個或多個匹配
+ 1個或多個匹配(等於{1,})
? 0個或1個匹配(等於{0,1})
{n} 指定數目的匹配
{n,} 不少於指定數目的匹配
{n,m} 匹配數目的範圍(m不超過255)
*/

#OR匹配,利用|,不能加空格
SELECT prod_name FROM products
WHERE prod_name REGEXP '1000|2000'
ORDER BY prod_name;
#利用[]匹配特定的字元
SELECT prod_name FROM products
WHERE prod_name REGEXP '[123] Ton'#返回1 ton和2 ton和3 ton;[^123]匹配除這些字元外的任何東西
ORDER BY prod_name;
#匹配範圍:[0-9],[a-z]
SELECT prod_name FROM products
WHERE prod_name REGEXP '[1-5] Ton'
ORDER BY prod_name;
#匹配特殊字元:.、[]|等,前面加\\轉義,用兩個反斜槓的原因:MySQL自己解釋一個,正則表示式庫解釋另一個
SELECT vend_name FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY vend_name;
#匹配多個例項
SELECT prod_name FROM products
WHERE prod_name REGEXP '\\([0-9] sticks?\\)'#?使s可選,\\(轉義(
ORDER BY prod_name;

SELECT prod_name FROM products
WHERE prod_name REGEXP '[[:digit:]]{4}'#[:digit:]匹配任意數字,{4}要求前面的字元出現4次 等價於 [0-9][0-9][0-9][0-9]
ORDER BY prod_name;
#定位符:匹配特定位置的文字 ^ $ [[:<:]]  [[:>:]]分別對應文字開始、結束、詞開始、結束
#不使用資料庫表進行正則表示式測試:(很有用)
SELECT 'hello' REGEXP '[0-9]';#不配返回0,匹配返回1

#第十章:建立計算欄位(fieled):執行時在SELECT語句內建立
#拼接欄位,兩列,如列印:name(location),利用Concat()函式,而其他資料庫一般用+或||
SELECT Concat(vend_name,'(',vend_country,')') FROM vendors ORDER BY vend_name;
#刪除右側多餘空格來整理資料,利用RTrim()函式,刪除左側空格:LTrim()
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') FROM vendors ORDER BY vend_name;
#使用列別名顯示,AS
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') AS vend_title FROM vendors ORDER BY vend_name;
#執行算術運算
SELECT prod_id,quantity,item_price, quantity*item_price AS expanded_price
FROM orderitems
WHERE order_num = 20005;
#測試函式,利用SELETC+函式
SELECT 3*2;
SELECT TRim('abc ');
SELECT Now();#返回當前日期和時間

#第十一章:使用資料處理函式,函式不便於移植,因此要做好註釋
#Upper() Lower() Left()返回串左邊的字元 Length() Locate()找出串的一個字串 Soundex() SubString() 

#日期和時間處理函式
/*
日期和時間採用相應的資料型別和特殊的格式儲存,以便能快速和
有效地排序或過濾,並且節省物理儲存空間。
一般,應用程式不使用用來儲存日期和時間的格式,因此日期和時
間函式總是被用來讀取、統計和處理這些值。由於這個原因,日期和時
間函式在MySQL語言中具有重要的作用。日期格式:yyyy-mm-dd
AddDate() 增加一個日期(天、周等)
AddTime() 增加一個時間(時、分等)
CurDate() 返回當前日期
CurTime() 返回當前時間
Date() 返回日期時間的日期部分
DateDiff() 計算兩個日期之差
Date_Add() 高度靈活的日期運算函式
Date_Format() 返回一個格式化的日期或時間串
Day() 返回一個日期的天數部分
DayOfWeek() 對於一個日期,返回對應的星期幾
Hour() 返回一個時間的小時部分
Minute() 返回一個時間的分鐘部分
Month() 返回一個日期的月份部分
Now() 返回當前日期和時間
Second() 返回一個時間的秒部分
Time() 返回一個日期時間的時間部分
Year() 返回一個日期的年份部分
*/
SELECT cust_id, order_num,order_date FROM orders
WHERE order_date = '2005-09-01';#不可靠
SELECT cust_id,order_num,order_date FROM orders
WHERE Date(order_date) = '2005-09-01';#提取出日期來比較
#檢索2005-09
SELECT cust_id,order_num,order_date FROM orders
WHERE Year(order_date) = 2005 AND Month(order_date) = 9;
#數值處理函式
/*
Abs() 返回一個數的絕對值
Cos() 返回一個角度的餘弦
Exp() 返回一個數的指數值
Mod() 返回除操作的餘數
Pi() 返回圓周率
Rand() 返回一個隨機數
Sin() 返回一個角度的正弦
Sqrt() 返回一個數的平方根
Tan() 返回一個角度的正切
*/

#第十二章:彙總資料
/*
AVG() 返回某列的平均值,忽略NULL的行
COUNT() 返回某列的行數
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和
*/
SELECT AVG(prod_price) AS avg_price FROM products
WHERE vend_id = 1003;

SELECT COUNT(cust_email) AS num_cust FROM customers;#對有電子郵件的客戶計數,忽略NULL行

SELECT AVG(DISTINCT prod_price) AS avg_price FROM products#排出相同的數值
WHERE vend_id = 1003;

#組合聚集函式:
SELECT COUNT(*) AS num_items,MIN(prod_price) AS price_min,MAX(prod_price) AS price_max
FROM products;

#第十三章:資料分組GROUP BY、HAVING
#建立分組
SELECT vend_id,COUNT(*) AS num_prods
FROM products
GROUP BY vend_id #通過vend_id進行邏輯分組
ORDER BY num_prods;#根據計數結果排序
#過濾分組:HAVING子句,不能用WHERE,因為WHERE基於分組聚集值而不是特定行值
SELECT cust_id,COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;#HAVING基於行值

SELECT vend_id, COUNT(*) AS num_prods FROM products
WHERE prod_price >= 10 
GROUP BY vend_id
HAVING COUNT(*) >= 2;

#GROUP BY 和 ORDER BY
SELECT order_num, SUM(quantity*item_price) AS ordertotal FROM orderitems
GROUP BY order_num
HAVING SUM(quantity*item_price) >=50
ORDER BY ordertotal;

/*
SELECT子句的順序和作用
子 句         說 明              是否必須使用
SELECT    要返回的列或表示式          是
FROM      從中檢索資料的表       僅在從表選擇資料時使用
WHERE       行級過濾					 否
GROUP BY   分組說明 		僅在按組計算聚集時使用
HAVING      組級過濾					 否
ORDER BY   輸出排序順序				     否
LIMIT     要檢索的行數 					否
*/


#第十四章:子查詢,即巢狀在其他查詢中的查詢
#獲取訂購物品TNT2的所有客戶,並檢索客戶資訊,從內向外
SELECT cust_name, cust_contact
FROM customers
WHERE cust_id 
IN (SELECT cust_id FROM orders
WHERE order_num
IN(SELECT order_num FROM orderitems
WHERE prod_id = 'TNT2'));
#統計每個客戶的訂單數目
SELECT cust_name,cust_state,
(SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id)#涉及外部查詢的子查詢
AS orders 
FROM customers
ORDER BY cust_name;

#第十五章:聯結表 ***重要!,一個表中儲存另外一個表的主鍵(外來鍵)即可形成聯結,保證所有聯結都有WHERE子句
#等值聯結
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
#內部聯結(不同的語法)(推薦使用,能讓讓你記住是;聯結關係)
SELECT vend_name,prod_name,prod_name
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
#聯結多個表
SELECT order_num, vend_name, prod_price, quantity
FROM vendors, products, orderitems
WHERE vendors.vend_id = products.vend_id
AND products.prod_id = orderitems.prod_id
AND order_num = 20005;

#第十六章:建立高階聯結:對被聯結的表使用表別名和聚集函式
SELECT cust_name, cust_contact
FROM customers AS c, orders AS o, orderitems AS oi
WHERE c.cust_id = o.cust_id
AND oi.order_num = o.order_num
AND prod_id = 'TNT2';

#利用自聯結代替子查詢,效率更高
#找出生產某問題商品供應商所生產的其他所有物品
SELECT prod_id, prod_name
FROM products #父查詢:該供應商生產的產品
WHERE
vend_id = (SELECT vend_id FROM products WHERE prod_id = 'DTNTR');#子查詢:找到供應商
#用子查詢替代:需要在一個商品表中查兩次
SELECT p1.prod_id, p1.prod_name
FROM products AS p1, products AS p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';

#自然聯結:使每個列只返回一次:對錶使用萬用字元
SELECT c.*,o.order_num,o.order_date, oi.prod_id, oi.quantity,oi.item_price
FROM customers AS c, orders AS o, orderitems AS oi
WHERE c.cust_id = o.cust_id
AND oi.order_num = o.order_num
AND prod_id = 'FB';

#外部聯結:許多聯結將一個表中的行與另一個表中的行相關聯。但有時候會需
#要包含沒有關聯行的那些行
#檢索所有客戶及其訂單
SELECT customers.cust_id, orders.order_num
FROM customers LEFT OUTER JOIN orders##LEFT:選擇customers(左邊)的所有行
ON customers.cust_id = orders.cust_id;

#使用帶聚集函式的聯結
#檢索所有客戶及其每個客戶所下的訂單數
SELECT customers.cust_name, customers.cust_id, COUNT(orders.order_num) AS num_prod
FROM customers INNER JOIN orders
ON customers.cust_id = orders.cust_id
GROUP BY customers.cust_id;

#第十七章:組合查詢:UNION:任何具有多個WHERE子句的SELECT語句都可以作為一個組合查詢給出
SELECT vend_id, prod_id, prod_price
FROM products
WHERE prod_price <= 5
UNION
SELECT vend_id, prod_id, prod_price
FROM products
WHERE vend_id IN(1001,1002);#將結果放在一個表中,這裡可以用OR代替
#note:使用UNION ALL,MySQL不取消重複的行。

#第十八章:全文字搜尋,對結果分等級,排序,出現的順序
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit');
#等同於但是不排序
SELECT note_text
FROM productnotes
WHERE note_text LIKE '%rabbit%';

SELECT note_text,
Match(note_text) Against('rabbit') AS rank#每一行返回一個等級,沒有的話等級為0,詞靠前的等級更高
FROM productnotes;#此句語法有問題

#使用查詢擴充套件p125,極大地增加了返回的行數
SELECT note_text
FROM productnotes
WHERE Match(note_text) Against('rabbit' WITH QUERY EXPANSION);

#布林文字搜尋:IN BOOLEAN MODE:p128


#第十九章:插入資料
#必須要指定列名
INSERT INTO customers(
#列名
)
VALUES(
),
(
);#可以同時插入多行

#還可以插入檢索出的資料,INSERT 與 SELECT組合
INSERT INTO customers()
SELECT cust_id,cust_contact,...
FROM custnew;#兩個表的列名不必一致


#第二十章:更新和刪除資料,UPDATE DELETE
UPDATE customers
SET cust_name = 'The Fudds',
	cust_email = '
[email protected]
' WHERE cust_id = 10005;#如果沒有WHERE將更新所有的行,一定要慎重!!! #可以用UPDATE IGNORE customers...復原 UPDATE IGNORE customers SET cust_name = 'The Fudds', cust_email = '[email protected]' WHERE cust_id = 10005; #刪除DELETE, TRUNCATE TABLE #更新和刪除使用原則 /* 除非確實打算更新和刪除每一行,否則絕對不要使用不帶WHERE 子句的UPDATE或DELETE語句。  保證每個表都有主鍵(如果忘記這個內容,請參閱第15章),儘可能 像WHERE子句那樣使用它(可以指定各主鍵、多個值或值的範圍)。  在對UPDATE或DELETE語句使用WHERE子句前,應該先用SELECT進 行測試,保證它過濾的是正確的記錄,以防編寫的WHERE子句不 正確。  使用強制實施引用完整性的資料庫(關於這個內容,請參閱第15 章),這樣MySQL將不允許刪除具有與其他表相關聯的資料的行。 */ #MySQL沒有undo撤銷功能 #第二十一章:建立和操縱表,看的不仔細 CREATE TABLE people ( pId int NOT NULL auto_increment, pName char(50) NOT NULL, pGender char(10) NOT NULL, pAge int NOT NULL, PRIMARY KEY(pId) )ENGINE=InnoDB; INSERT INTO people ( pId,pName,pGender,pAge ) VALUES(1,'wjj','male','22'); SELECT pId,pName,pGender,pAge FROM people WHERE people.pName = 'wjj'; #第二十二章:使用檢視:包含的是一個SQL查詢,檢視是一種虛擬的表 /* 建立一個名為productcustomers的檢視,它聯結三個 表,以返回已訂購了任意產品的所有客戶的列表。如果執行 SELECT * FROM productcustomers,將列出訂購了任意產品的客戶。 */ CREATE VIEW productcustomers AS SELECT cust_name, cust_contact, prod_id FROM customers, orders, orderitems WHERE customers.cust_id = orders.cust_id AND orderitems.order_num = orders.order_num; select * FROM productcustomers; SELECT cust_name,cust_contact FROM productcustomers WHERE prod_id = 'TNT2'; #用檢視重新格式化檢索出的資料 CREATE VIEW vendorlocations AS SELECT Concat(RTrim(vend_name), '(', RTrim(vend_country), ')') AS vend_title FROM vendors ORDER BY vend_name; #可重用 SELECT * FROM vendorlocations; #用檢視過濾掉不想要的資料 CREATE VIEW customeremaillist AS SELECT cust_id, cust_name, cust_email FROM customers WHERE cust_email IS NOT NULL; SELECT * FROM customeremaillist; #使用檢視簡化計算欄位 CREATE VIEW orderitemsexpanded AS SELECT order_num, prod_id, quantity, item_price, quantity*item_price AS expanded_price FROM orderitems; SELECT * FROM orderitemsexpanded WHERE order_num = 20005 ORDER BY expanded_price; #更新檢視:一般來說檢視只用於檢索不用於更新 #第二十三章:使用儲存過程(可以視為批檔案):為以後的使用而儲存的一條或多條MySQL語句的集合 #執行儲存過程(呼叫) #建立:一個返回產品平均價格的儲存過程 DELIMITER // CREATE PROCEDURE productpricing() BEGIN SELECT Avg(prod_price) AS priceaverge FROM products; END // #沒有引數,沒有返回資料 #DELIMITER //告訴命令列實用程式使用//作為新的語 #句結束分隔符,可以看到標誌儲存過程結束的END定義為END #//而不是END; DELIMITER ;#除\符號外,任何字元都可以用作語句分隔符 #使用 CALL productpricing();#執行剛建立的儲存過程並顯示返回的結果 #刪除 DROP PROCEDURE productpricing; #使用引數:所有變數都必須以@開始 /* 關鍵字OUT指出相應的引數用來從儲存過程傳出一個值(返回給呼叫者)。 MySQL支援IN(傳遞給儲存過程)、 OUT(從儲存過程傳出,如這裡所用) 和INOUT(對儲存過程傳入和傳出)型別的引數。 */ DELIMITER // CREATE PROCEDURE productpricing( OUT pl DECIMAL(8,2), OUT ph DECIMAL(8,2), OUT pa DECIMAL(8,2) ) BEGIN SELECT Min(prod_price) INTO pl FROM products; SELECT Max(prod_price) INTO ph FROM products; SELECT Avg(prod_price) INTO pa FROM products; END // DELIMITER ; DROP PROCEDURE productpricing; CALL productpricing(@pricelow,@pricehigh,@priceaverage); #顯示引數值 SELECT @pricelow, @pricehigh, @priceaverage; DELIMITER // CREATE PROCEDURE ordertotal( IN onumber INT, OUT ototal DECIMAL(8,2) ) BEGIN SELECT Sum(item_price* quantity) FROM orderitems WHERE order_num = onumber INTO ototal; END // DROP PROCEDURE ordertotal// DELIMITER ; CALL ordertotal(20005, @total); SELECT @total; CALL ordertotal(20009,@total);#可重複呼叫 SELECT @total; #建立智慧儲存過程 DELIMITER // -- Name: ordertotal -- Parameters: onumber = order number -- taxable = 0 if not taxable, 1 if taxable -- ototal = order total variable CREATE PROCEDURE ordertotal( IN onumber INT, IN taxable BOOLEAN, OUT ototal DECIMAL(8,2)#八位兩個小數 ) COMMENT 'Obtain order total, optionally adding tax' BEGIN -- 宣告變數 DECLARE total DECIMAL(8,2); DECLARE taxrate INT DEFAULT 6; -- Get the order total SELECT Sum(item_price * quantity) FROM orderitems WHERE order_num = onumber INTO total; -- Is this taxable IF taxable THEN SELECT total + (total/100*taxrate) INTO total; END IF; SELECT total INTO ototal; END// DELIMITER ; DROP PROCEDURE ordertotal; CALL ordertotal(20005,0,@total); SELECT @total; CALL ordertotal(20005,1,@total); SELECT @total; #檢查儲存過程 SHOW CREATE PROCEDURE ordertotal; #第二十四章:使用遊標:前進後退一行或多行,用於互動式應用 #遊標(cursor)是一個儲存在MySQL伺服器上的資料庫查詢, #它不是一條SELECT語句,而是被該語句檢索出來的結果集。 DELIMITER // CREATE PROCEDURE processorders() BEGIN -- 宣告定義遊標 DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- 開啟遊標 OPEN ordernumbers; -- 關閉,釋放資源 CLOSE ordernumbers; END// DELIMiTER ; DELIMITER // #使用遊標資料 CREATE PROCEDURE processorders1() BEGIN DECLARE o INT; DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; OPEN ordernumbers; -- Get order number FETCH ordernumbers INTO o; #指定檢索什麼資料(所需的列) CLOSE ordernumbers; END//#此例對檢索出的資料未作處理 #迴圈檢索資料 CREATE PROCEDURE processorders2() BEGIN DECLARE done BOOLEAN DEFAULT 0; DECLARE o INT; DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- Declare continue handler DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;#控制代碼,必須在遊標之後定義 OPEN ordernumbers; -- Loop through all rows REPEAT -- Get order number FETCH ordernumbers INTO o; #迴圈內可以放入任意需要的處理 -- End of loop UNTIL done END REPEAT; CLOSE ordernumbers; END// #迴圈檢索資料並對索引出的資料處理 CREATE PROCEDURE processorders3() BEGIN DECLARE done BOOLEAN DEFAULT 0; DECLARE o INT; DECLARE t DECIMAL(8,2); DECLARE ordernumbers CURSOR FOR SELECT order_num FROM orders; -- Declare continue handler DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;#控制代碼,必須在遊標之後定義 -- Create a table to store the results CREATE TABLE IF NOT EXISTS `ordertotals`( `order_num` INT, `total` DECIMAL(8,2), PRIMARY KEY(`order_num`) )ENGINE = InnoDB; OPEN ordernumbers; -- Loop through all rows REPEAT -- Get order number FETCH ordernumbers INTO o; #迴圈內可以放入任意需要的處理 -- Get the total for this order CALL ordertotal(o,1,t); INSERT INTO ordertotals(order_num,total) VALUES(o,t); -- End of loop UNTIL done END REPEAT; CLOSE ordernumbers; END//#note:不知道為什麼建立不成功 DELIMITER ; DROP PROCEDURE processorders3; SELECT * FROM ordertotals; CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` VARCHAR(100) NOT NULL, `runoob_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `runoob_id` ) )ENGINE=InnoDB; DROP TABLE runoob_tbl ; -- Create a table to store the results CREATE TABLE IF NOT EXISTS `ordertotals`( `order_num` INT, `total` DECIMAL(8,2), PRIMARY KEY(`order_num`) )ENGINE = InnoDB; #第二十五章,使用觸發器:某條語句在事件發生時自動執行,針對DELETE、INSERT、UPDATE CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added' into @ee; select * from products; DROP TRIGGER newproduct; CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT NEW.order_num into @ee; INSERT INTO orders(order_date, cust_id) VALUE(Now(),10001); SELECT @ee; #DELETE觸發器 DELIMITER // CREATE TRIGGER deleteorder BEFORE DELETE ON orders FOR EACH ROW BEGIN INSERT INTO archive_orders(order_num, order_date, cust_id)#刪除之前儲存到存檔表中 VALUES(OLD.order_num, OLD.order_date, OLD.cust_id); END// #UPDATE觸發器 #第二十六章:管理事務處理(ROLLBACK、COMMIT、保留點、更改預設的提交行為) DELIMITER ; SELECT * FROM ordertotals; START TRANSACTION; DELETE FROM ordertotals; SELECT * FROM ordertotals; ROLLBACK; SELECT * FROM ordertotals; #第二十七章:使用字符集和校對順序 #第二十八章:安全管理 /* MySQL使用者賬號和資訊儲存在名為mysql的MySQL資料庫中。一般 不需要直接訪問mysql資料庫和表(你稍後會明白這一點),但有時需要 直接訪問。需要直接訪問它的時機之一是在需要獲得所有使用者賬號列表 時 */ USE mysql; SELECT user FROM user; #獲取資料庫所有的表名稱 SELECT table_name FROM information_schema.Tables ORDER BY table_name;#結果中包含user #建立使用者賬號 CREATE USER wjj IDENTIFIED BY 'aaaaaa'; RENAME USER wjj TO wangjinju; DROP USER wangjinju; SHOW GRANTS FOR wangjinju;#顯示許可權 #賦許可權:GRANT GRANT SELECT ON crashcourse.* TO wangjinju;#只讀許可權SELECT REVOKE SELECT ON crashcourse.* FROM wangjinju;#撤銷許可權 #更改密碼(口令) SET PASSWORD FOR wangjinju = Password('aaaaaab'); #第二十九章:資料庫維護 #備份資料 /* 使用命令列實用程式mysqldump轉儲所有資料庫內容到某個外部 檔案。在進行常規備份前這個實用程式應該正常執行,以便能正 確地備份轉儲檔案。  可用命令列實用程式mysqlhotcopy從一個數據庫複製所有資料 (並非所有資料庫引擎都支援這個實用程式)。  可以使用MySQL的BACKUP TABLE或SELECT INTO OUTFILE轉儲所 有資料到某個外部檔案。這兩條語句都接受將要建立的系統檔案 名,此係統檔案必須不存在,否則會出錯。資料可以用RESTORE TABLE來複原。 */ #資料庫維護、檢查 ANALYZE TABLE orders;#檢查表鍵是否正確 CHECK TABLE orders,orderitems; #如果從一個表中刪除大量資料, #應該使用OPTIMIZE TABLE來收回所用的空間,從而優化表的性 OPTIMIZE TABLE orders;