Chapter Database

Preview:

Citation preview

Suphitcha Chanrueang7121311 การบรหิารและจดัการฐานขอ้มลู

ประวตัแิละความเป็นมาของ SQLSQL (Structured Query Language ) เป็นภาษามาตรฐานบนระบบฐานข้อมลู

เชิงสมัพนัธ์ ชดุคําสัง่ หรือภาษา SQL นัน่ถกูพฒันาจากแนวความคิดทางคณิตศาสตร์ คือ

Relational Algebra และ Relational Calculus ตอ่มาได้ถกูกําหนดให้เป็นรูปแบบมาตรฐานโดยสถาบนั American National 

Standards Institue(ANSI)  ระบบการจดัการฐานข้อมลูที่รองรับ SQL เชน่ ORACLE, DB2, SYBASE, Informix, MS‐SQL, MS‐Access และ MS‐FoxPro

วตัถปุระสงคข์อง SQL

• สร้างฐานข้อมลูและโครงสร้างรีเลชนั

• สนบัสนนุงานด้านการจดัการข้อมลูพืน้ฐาน การเพิ่ม การปรับปรุง และการลบ

ข้อมลูจากรีเลชนั

• สนบัสนนุการควิรีข้อมลูพืน้ฐานตลอดจนคิวรีข้อมลูขัน้สงูที่มีความซบัซ้อน รวมทัง้

ความสามารถในการแปลงข้อมลูดิบให้เป็นสารสนเทศ

การใชง้านภาษา SQL

• แบบโต้ตอบ (Interactive SQL)– ยสูเซอร์สามารถใช้งานชดุคําสัง่ SQL โดยโต้ตอบกนับนจอภาพ

• แบบฝังในตวัโปรแกรม (Embedded SQL)เป็นการเขียนชดุคําสัง่ภาษา SQL ไว้ในโปรแกรม– Embedded SQL Statements  – Application Programming Interface (API)

ประเภทของคําสัง่ภาษา SQL

• ภาษานิยามข้อมลู (Data Definition Language : DDL)– ใช้ในการสร้างฐานข้อมลู กําหนดโครงสร้างข้อมลู

• ภาษาจดัการข้อมลู (Data Manipulation Language : DML)– ใช้ในการอปัเดต เพิ่ม ปรับปรุง และการคิวรีข้อมลูในฐานข้อมลู

• ภาษาควบคมุข้อมลู (Data Control Language : DCL)– ใช้ในการกําหนดสทิธิในการเข้าถงึข้อมลูในฐานข้อมลู

ภาษานยิามขอ้มลู (Data Definition Language : DDL)

• CREATE   คําสัง่ที่ใช้ในการสร้าง– CREATE TABLE สร้างตาราง

– CREATE INDEX สร้างดชันี

– CREATE VIEW สร้างวิว

• DROP  คําสัง่ที่ใช้ในการลบ– DROP TABLE ลบตาราง

– DROP INDEX  ลบดชันี

– DROP VIEW ลบวิว

• ALTER  คําสัง่ที่ใช้ในการเปลีย่นแปลงโครงสร้างตาราง

การสรา้งตาราง (CREATE TABLE)CREATE TABLE tablename(

column_name datatype [ NULL |NOT NULL][DEFAULT default_value] [column_constraint_clause]…[,column_name datatype [ NULL |NOT NULL][DEFAULT default_value] [column_constraint_clause]…]…[table_constraint_clause]..);

CREATE TABLE staff(sno VARCHAR(5) NOT NULL,fname VARCHAR(15) NOT NULL,lname VARCHAR(15) NOT NULL,sex CHAR(1) NOT NULL DEFAULT F,dob DATETIME NOT NULL);

รูปแบบ

ตวัอย่าง

การลบตาราง (DROP TABLE)

DROP TABLE tablename;

DROP TABLE property_for_rent;

รูปแบบ

ตวัอย่าง

การสรา้งดชันแีละลบดชันี

CREATE [UNIQUE] INDEX index_name ON table_name (column [ASC|DESC] […]);

CREATE INDEX sno_ind ON staff(sno);CREATE INDEX pno_ind ON property_for_rent(pno);CREATE INDEX rent_ind ON property_for_rent (area,rent);CREATE INDEX rent_ind ON property_for_rent (area);

รูปแบบ

ตวัอย่าง

DROP INDEX index_name;

DROP INDEX rent_ind;

การเปลีย่นแปลงโครงสรา้งตาราง (ALTER TABLE)

ALTER TABLE tablename[COMMAND [COLUMN] column_name data_type [CONSTRAINT]];

ALTER TABLE staffADD (bonus DECIMAL(7,2));

รูปแบบ

ตัวอย่าง

โดยที่ COMMAND สามมารถเป็นคาํสั่งต่าง ๆ เช่น

- ADD คือการเพิ่มคอลัมน์หรือข้อจาํกัด (constraint)

- MODIFY คือการแก้ไขเปลี่ยนแปลงคอลัมน์

- DROP คือการลบคอลัมน์

ALTER TABLE staffMODIFY (bonus DECIMAL(9,2));

ALTER TABLE staffDROP bonus;

การสรา้งววิ (CREATE VIEW)

CREATE VIEW view_name [(column_name [, …])]AS subselect [WITH [CASCADED | LOCAL] CHECK OPTION];

รูปแบบ

CREATE VIEW STAFF_VIEWAS SELECT sno, fname, lname, position, bnoFROM staff;

ตัวอย่าง

ภาษาจัดการขอ้มลู (Data Manipulation Language : DML)

• SELECT  ใช้สําหรับคิวรีข้อมลูในฐานข้อมลู

• INSERT ใช้สําหรับเพิ่มข้อมลูในตาราง

• UPDATE ใช้สําหรับการอปัเดตข้อมลูในตาราง

• DELETE  ใช้สําหรับลบข้อมลูจากตาราง

SELECT Statement

SELECT [DISTINCT | ALL] { * | column_expression[ AS new_name ]][, ...]}FROM table_name [ alias ] [ , … ][ WHERE condition ][ GROUP BY column_list ] [ HAVING condition ][ ORDER BY column_list ] ;

รูปแบบ

โดยลําดับการประมวลผลในชดุคําสัง่ SELECT มดีงันี้- FROM กําหนดตารางทีต่อ้งการใชง้าน- WHERE สรา้งเงือ่นไขเพือ่กรอง (filters) แถวทีต่อ้งการ- GROUP BY จัดกลุม่แถวทีม่คีา่คอลัมนเ์ดยีวกนั- HAVING กรองกลุม่เนือ้หาในบางเงือ่นไขจาก GROUP BY- ORDER BY กําหนดใหเ้รยีงลําดบัผลลพัธ ์โดยที่

ASC เรยีงจากนอ้ยไปมากDESC เรยีงจากมากไปนอ้ย

ตวัอยา่งการใชค้ําสัง่ SELECT

SELECT sno, fname, lname, address, tel_no, position, sex, dob, salary, bnoFROM staff;

หรอืSELECT *FROM staff;

การเรียกดขู้อมูลทุก ๆ คอลัมน์

แสดงรายละเอียดของ Staff ทกุ ๆ คน

ตวัอยา่งการใชค้ําสัง่ SELECTการเรียกดขู้อมูลบางคอลัมน์

แสดงรหสั ชื่อ และเงินเดือน ของ Staff

SELECT sno, fname, lname, salaryFROM staff ORDER BY sno DESC ;

การเรียกดขู้อมูลด้วยการไม่ให้แสดงข้อมูลที่ซํา้ ๆ

แสดงรหสับ้านเชา่ (Property) ที่มีลกูค้ามาเยี่ยมชม

SELECT DISTINCT pnoFROM viewing;

ตวัอยา่งการใชค้ําสัง่ SELECTการคาํนวณค่าในคอลัมน์ด้วยนิพจน์ทางคณิตศาสตร์ + , - , * , /

คํานวณคา่คอมมิชชนั 5 % จากยอดเงินเดือน

SELECT sno, fname, lname, salary*0.05FROM staff;

กําหนดชื่อคอลมัน์ใหมท่ี่ได้จากการคํานวณ

SELECT sno, fname, lname, salary*0.05 AS commissionFROM staff;

ตวัอยา่งการใชค้ําสัง่ SELECTการใช้เงื่อนไขเพื่อเปรียบเทยีบ

แสดงรายชื่อพนกังาน (Staff) ที่มีเงินเดือนมากกวา่ 10,000 บาท

SELECT sno, fname, lname, position, salaryFROM staffWHERE salary>10000;

เครือ่งหมายเปรยีบเทยีบ (comparison operatiors)

= เทา่กบั< นอ้ยกวา่> มากกวา่<= นอ้ยกวา่หรอืเทา่กบั>= มากกวา่หรอืเทา่กบั<> ไมเ่ทา่กบั

ตวัอยา่งการใชค้ําสัง่ SELECTการใช้เครื่องหมายทางตรรกะ (logical operators)

โดยใช้ข้อความ AND , OR และ NOT

SELECT bno, street, area, city, pcodeFROM branchWHERE city = ‘Chaingmai’ OR city = ‘Bangkok’;

ตวัอยา่งการใชค้ําสัง่ SELECTการใช้เงื่อนไข BETWEEN / NOT BETWEEN

แสดงข้อมลูพนกังานที่มีเงินเดือนระหวา่ง 20,000 ถงึ 30,000 บาท

SELECT sno, fname, lname, position, salaryFROM staffWHERE salary BETWEEN 20000 AND 30000;

หรอืSELECT sno, fname, lname, position, salaryFROM staffWHERE salary >= 20000 AND salary <= 30000;

ตวัอยา่งการใชค้ําสัง่ SELECTการใช้เงื่อนไข IN / NOT IN

แสดงข้อมลู Staff ทัง้หมดที่มีตําแหน่งเป็น ‘Manager’ และ ‘Deputy’

SELECT sno, fname, lname, positionFROM staffWHERE position IN (‘Manager’, ‘Deputy’);

หรอืSELECT sno, fname, lname, positionFROM staffWHERE position = ‘Manager’ OR position = ‘Deputy’;

ตวัอยา่งการใชค้ําสัง่ SELECT

LIKE และ NOT LIKE เป็นโอเปอเรเตอร์ที่ใช้ในการค้นหาข้อมลูตวัอกัษร โดยใช้สญัลกัษณ์ % และ _  โดยที่

% แทนตวัอกัษรหลายตวั เชน่ sno LIKE ‘SG%’  หมายถงึ ค้นหา Staff_No ที่ขึน้ต้นด้วย SG ทัง้หมด

_  แทนตวัอกัษร 1 ตวัอกัษร เชน่ fname LIKE ‘_o%’  หมายถงึ ค้นหาชื่อที่มีตวัอกัษรขึน้ต้นด้วยอะไรก็ได้หนึง่ตวั ตวัอกัษรที่สองต้องเป็นตวั o และที่เหลือคืออกัษรใด ๆ ก็ได้

ใน MS‐Access ใช้สญัลกัษณ์ * แทน % และใช้ ? แทน _

ตวัอยา่งการใชค้ําสัง่ SELECTค้นหา Staff ที่มีที่อยู ่ อยูใ่นกรุงเทพฯ

SELECT sno, fname, lname, address, salaryFROM staffWHERE address LIKE ‘*Bangkok*’;

ค้นหา Staff ที่ไมไ่ด้ อยูใ่นกรุงเทพฯ

SELECT sno, fname, lname, address, salaryFROM staffWHERE address NOT LIKE ‘*Bangkok*’;

ตวัอยา่งการใชค้ําสัง่ SELECTการใช้เงื่อนไข IS NULL / IS NOT NULL

แสดงรายละเอียดของ Viewing ของ Property PG04 ที่ลกูค้าไมไ่ด้ comment ใดๆ

SELECT rno, dateFROM viewingWHERE pno = ‘PG04’ AND comment IS NULL;

ตวัอยา่งการใชค้ําสัง่ SELECTการเรียงลาํดบัคอลัมน์เดยีว (Single column ordering)

แสดงข้อมลู Staff ด้วยการเรียงลําดบัตามเงินเดือนจากมากไปน้อย

SELECT sno, fname, lname, salaryFROM staffORDER BY salary DESC;

การเรียงลาํดบัหลายคอลัมน์ (Multiple column ordering)

SELECT pno, type, rooms, rentFROM property_for_rentORDER BY type,rent DESC;

การใชฟ้ังกช์นัการรวมใน SQL(The SQL Aggregate Functions)

• COUNT  ฟังก์ชนัการนบัจํานวน

• SUM   ฟังก์ชนัหาผลรวม

• AVG ฟังก์ชนัหาคา่เฉลี่ย

• MIN ฟังก์ชนัหาคา่ตํ่าสดุ

• MAX  ฟังก์ชนัหาคา่สงูสดุ

การใชฟ้ังกช์นัการรวมใน SQL(The SQL Aggregate Functions)

การใช้ฟังก์ชัน COUNT

เชน่ อยากทราบจํานวนบ้านเช่าที่มีคา่เช่ามากกวา่ 350 บาทตอ่วนั

SELECT COUNT(*) AS countFROM property_for_rentWHERE rent >350;

การใช้ฟังก์ชัน COUNT ร่วมกับฟังก์ชัน SUM

เชน่ ต้องการทราบวา่มีผู้จดัการอยูก่ี่คน และยอดรวมของเงินเดือนของผู้จดัการ

ทัง้หมดคือจํานวนเทา่ไร

SELECT COUNT(sno) AS count, SUM(salary) AS sumFROM staffWHERE position = ‘Manager’;

การใชฟ้ังกช์นัการรวมใน SQL(The SQL Aggregate Functions)

การใช้ฟังก์ชัน MIN, MAX, AVG

เชน่ ต้องการทราบยอดตํ่าสดุ ยอดสงูสดุ และยอดเฉลี่ยของเงินเดือนพนกังาน

(Staff)SELECT MIN(salary) AS min, MAX(salary) AS max,AVG(salary) AS avgFROM staff;

การใชป้ระโยค GROUP BY

เป็นการจดักลุม่แยกตามประเภทคา่ในแตล่ะคอลมัน์

การใช้ GROUP BY

เชน่ ต้องการทราบจํานวนพนกังานที่ทํางานอยูใ่นแตล่ะสาขา และทําการ

หายอดรวมเงินเดือนพนกังานที่จะต้องจ่ายในแตล่ะสาขา

SELECT bno, COUNT(sno) AS count, SUM(salary) AS sumFROM staffGROUP BY bnoORDER BY bno;

การใชป้ระโยค HAVING

จะใช้งานร่วมกบัประโยค GROUP BY เสมอ โดยเป็นการสร้างเงื่อนไขเพื่อดขู้อมลูบางสว่น

การใช้ HAVING

เชน่ แสดงสาขาที่มีจํานวนสมาชิกของ Staff ที่มากกวา่หนึง่คน, ค้นหา

จํานวน Staff ที่ทํางานในแตล่ะสาขา และหาผลรวมของเงินเดือน

SELECT bno, COUNT(sno) AS count, SUM(salary) AS sumFROM staffGROUP BY bnoHAVING COUNT(sno)>1ORDER BY bno;

Subqueries หรอื Nested query

การใช้คําสัง่ SELECT ซ้อนกนัเพื่อให้แสดงผลที่ซบัซ้อนขึน้

เชน่ ต้องการแสดงข้อมลู Staff ที่ทํางานในสาขาที่ตัง้อยูท่ี่ 143

Wipavadee Rd.

SELECT bno, fname, lname, positionFROM staffWHERE bno =

(SELECT bnoFROM branchWHERE street =‘143 Wipavadee Rd.’);

Subqueries หรอื Nested query

การใช้ Subquery ร่วมกับฟังก์ชันการรวม (Aggregate function)

เชน่ ให้แสดงข้อมลู Staff ที่มีเงินเดือนสงูกวา่เงินเดือนเฉลี่ย (average

salary) รวมทัง้แสดงสว่นตา่งของเงินเดือนวา่สงูกวา่เงินเดือนเฉลี่ยจํานวนเทา่ไร

SELECT sno, fname, lname, position, salary-(SELECT avg(salary) FROM staff)AS sal_diffFROM staffWHERE salary > (SELECT avg(salary)

FROM staff);

Subqueries หรอื Nested query

การใช้ Nested Subquery ด้วยการใช้ IN

เชน่ แสดงบ้านเช่า (properties) ที่ดแูลโดย Staff ที่ทํางานอยูใ่นสาขาที่

ตัง้อยูท่ี่ 143 Wipavadee Rd.

SELECT pno, street, area, city, pcode, type, rooms, rentFROM property_for_rentWHERE sno IN

(SELECT snoFROM staffWHERE bno =

(SELECT bnoFROM branchWHERE street = ‘143 Wipavadee Rd.’));

การ Join อยา่งงา่ย

การ Join เป็นการนําตารางสองตารางขึน้ไปมารวมกนัใต้เงื่อนไขที่กําหนด

การ Join อย่างง่าย (Simple join)

เชน่ จงแสดงชื่อของผู้ เช่า (Renters) หรือลกูค้าที่มาดบู้านเชา่ (Property)

ทัง้หมด

SELECT r.rno, fname, lname, pno, commentFROM renter AS r, viewing AS vWHERE r.rno = v.rnoORDER BY r.rno;

การ Join อยา่งงา่ยจงแสดงสาขาตา่ง ๆ ด้วยการแสดงชื่อของ Staff ที่ดแูลจดัการบ้านเช่า

รวมทัง้บ้านเชา่ที่ได้รับการดแูลจาก Staff

SELECT s.bno, s.sno, fname, lname, pnoFROM staff AS s, property_for_rent AS pWHERE s.sno = p.snoORDER BY s.bno, s.sno;

การ Join อยา่งงา่ย

การ Join สามตาราง

จงแสดงรายการสาขาตา่ง ๆ ซึง่ประกอบด้วย Staff ที่ดแูลบ้านเชน่ โดยให้

มีรายละเอียด City ของแตล่ะสาขาด้วย

SELECT b.bno, b.city, s.sno, fname, lname, pnoFROM branch AS b, staff AS s, property_for_rent AS pWHERE b.bno = s.bno AND s.sno = p.snoORDER BY b.bno, s.sno, pno;

Inner Join

ตาราง 1 ตาราง 2

ขอ้มลูทีต่รงกนั

Inner Join เป็นการเลือกข้อมลูจากหลายตารางโดยการ

จบัคูแ่ถวที่มีข้อมลูตรงกนัของ 2 ตาราง ที่ Join กนั

SELECT ชือ่คอลมัน1์ , ชือ่คอลมัน2์ , ....... FROM ชือ่ตาราง1 INNER JOIN ชือ่ตาราง2ON ชือ่ตาราง1.ชือ่คอลมัน ์= ชือ่ตาราง2.ชือ่คอลมัน์

รูปแบบ

INNER JOIN

SELECT *FROM Worker INNER JOIN AssignON Worker.WK_ID = Assign.WK_ID

Left Outer Join

ตาราง 1 ตาราง 2

ขอ้มลูทีต่รงกนั

แสดงผลลพัธ์เป็นแถวทัง้หมดในตารางที่อยูท่างซ้ายของคําสัง่ Left

Outer Join สว่นแถวของตารางทางด้านขวาที่ไมส่ามารถจบัคูไ่ด้จะแสดง

เป็นคา่วา่ง

SELECT ชือ่คอลมัน1์ , ชือ่คอลมัน2์ , ....... FROM ชือ่ตาราง1 LEFT OUTER JOIN ชือ่ตาราง2ON ชือ่ตาราง1.ชือ่คอลมัน ์= ชือ่ตาราง2.ชือ่คอลมัน์

Left Outer Join

SELECT Worker.WK_ID, Worker.WK_NAME, Assign.BLDG_IDFROM Worker LEFT JOIN Assign ON Worker.WK_ID = Assign.WK_ID;

การ UNION, INTERSECT, EXCEPT

การ UNION

จงแสดง area ทัง้หมดของสาขา(branch) และบ้านเช่า (property)

(SELECT areaFROM branch WHERE area IS NOT NULL)UNION(SELECT areaFROM property_for_rentWHERE area IS NOT NULL);

การ UNION, INTERSECT, EXCEPT

การ INTERSECT

จงแสดง city ที่มีอยูท่ัง้ในสาขา(branch) และบ้านเช่า (property)

(SELECT cityFROM branch )INTERSECT(SELECT cityFROM property_for_rent);

การ UNION, INTERSECT, EXCEPT

การใช้ EXCEPT

แสดง city ที่มีอยูใ่นสาขา(branch) แตไ่มม่ีในบ้านเช่า

(SELECT cityFROM branch )EXCEPT(SELECT cityFROM property_for_rent);

การบนัทกึขอ้มลู ( INSERT )

• การป้อนข้อมลูใหมล่งในตาราง

INSERT INTO table_name [(column_list)]VALUES (data_value_list);

รูปแบบ

INSERT INTO staff(sno, fname, lname, position, salary, bno)VALUES (‘SG44’, ‘Thidarat’, ‘Srithanachai’, ‘Assistant’, 10000, ‘B3’);

ตัวอย่าง

INSERT INTO staffVALUES (‘SG44’, ‘Thidarat’, ‘Srithanachai’,NULL, NULL ‘Assistant’,

NULL, NULL, 10000, ‘B3’);

การบนัทกึขอ้มลู ( INSERT )

• การคดัลอกตาราง

INSERT INTO table_name [(column_list)]SELECT

รูปแบบ

INSERT INTO staff_managerSELECT *FROM staffWHERE position=‘Manager’;

ตัวอย่าง

การปรับปรงุขอ้มลู (UPDATE)

UPDATE table_nameSET column_name1 = data_value1 [,column_name2 = data_value2…][WHERE search_condition];

รูปแบบ

UPDATE staffSET salary = salary * 1.05;

ตัวอย่าง เช่น ต้องการขึน้เงนิเดอืนเพิ่มขึน้ 5 % ให้กับพนักงานทุกคน

UPDATE staffSET salary = salary * 1.07WHERE position=‘Manager’;

ต้องการขึน้เงนิเดอืน 7 % ให้กับผู้จัดการ

การลบขอ้มลู (DELETE)

DELETE from table_name[WHERE search_condition];

รูปแบบ

Delete from viewingWHERE pno = ‘PG04’;

ตัวอย่าง

Delete from viewing

ภาษาควบคมุขอ้มลู (Data Control Language : DCL)

• คําสัง่ GRANT ใช้สําหรับกําหนดสิทธิในการเข้าถงึข้อมลูวา่จะใช้ยสูเซอร์คนใดมีสทิธิ์ในการจดัการข้อมลูในตารางหรือวิว

ใดบ้าง

• คําสัง่ REVOKEใช้สําหรับยกเลกิสิทธิบางสิทธิ

คําสัง่ GRANT

GRANT { privilege_list | ALL PRIVILEGES }ON object_nameTO { authorization_id_list | PUBLIC }

[ WITH GRANT OPTION ]

รูปแบบ

Privilege_list คือสทิธิที่อาจกําหนดได้มากกวา่หนึง่ ซึง่ประกอบด้วย

SELECT

DELETE

INSERT [ (column_name [ , …] ) ]

UPDATE [ (column_name [ , …] ) ]

REFERENCES [ (column_name [ , …] ) ]

USAGE

คําสัง่ GRANT

GRANT ALL PRIVILEGESON staffTO manager WITH GRANT OPTION;

กําหนดให้ยสูเซอร์ผู้จดัการ (manager) มีสทิธิเต็มรูปแบบ (full privileges) ใน

ตาราง Staff นัน่หมายถงึ ยสูเซอร์ manager สามารถทําการ SELECT, INSERT, UPDATE,

DELETE ในตาราง Staff

GRANT SELECT, UPDATE(salary)ON staffTO admin;

กําหนดให้ยสูเซอร์ admin มีสทิธิในการ UPDATE คอลมัน์ salary ในตาราง Staff

คําสัง่ GRANT

GRANT SELECTON staffTO personnel, deputy;

กําหนดให้ยสูเซอร์ personnel และ deputy มีสทิธิในการเรียกดขู้อมลูจากตาราง

Staff

GRANT SELECTON branch;TO PUBLIC;

กําหนดให้ยสูเซอร์ทกุ ๆ คน มีสทิธิในการเรียกดขู้อมลูจากตาราง Branch

คําสัง่ REVOKE

REVOKE [GRANT OPTION FOR] {privilege_list | ALL PRIVILEGER}ON object_nameFROM {authorizationL_id_list | PUBLIC} [RESTRICT | CASCADE];

รูปแบบ

REVOKE SELECTON branchFROM PUBLIC;

ตัวอย่าง

ยกเลกิสทิธิของยสูเซอร์ทกุ ๆ คนในการเรียกดขู้อมลูจากตาราง Branch

คําสัง่ REVOKE

REVOKE ALL PRIVILEGESON staffFROM deputy;

ยกเลกิสทิธิทัง้หมดของยเูซอร์ deputy ในการจดัการกบัตาราง Staff

คําสัง่ REVOKE

Recommended