CREATE TABLE student
(
s_no char(10) PRIMARY KEY,
s_name char(24),
s_age int,
s_sex char(4),
s_dept char(20),
s_major char(30),
s_class char(10)
);
CREATE TABLE course
(
c_no int PRIMARY KEY,
c_name char(18),
c_credit int
);
CREATE TABLE cs
(
s_no char(10),
c_no int,
cs_grade int,
PRIMARY KEY(s_no,c_no)
);
CREATE TABLE XXX(表名)
(
XX(列名) XXX(类型) XXX(属性)
);
DESC student;(等价于SHOW COLUMNS FROM student;)
DESC course;
DESC cs;
/*此处,我使用的是我&&舍友的信息*/
/*往student表中插入数据(安全插法)*/
INSERT INTO student(s_no,s_name,s_age,s_sex,s_dept,s_major,s_class)
VALUES
('04161210','HuangChao',20,'man','CS','Computer science&technology','1608'),
('04161211','ZhuYu',21,'man','CS','Computer science&technology','1608'),
('04161212','YangJiaLiang',20,'man','CS','Computer science&technology','1608'),
('04161213','WangYuXiang',20,'man','CS','Computer science&technology','1608'),
('04161214','CuiYuHang',20,'man','CS','Computer science&technology','1608'),
('04161215','XueJiangWei',20,'man','CS','Computer science&technology','1608');
/*往course表中插入数据(不安全插法:未指明各数据项)*/
INSERT INTO course
VALUES
(1,'HighMath',6),
(2,'DataStruct',5),
(3,'English',4),
(4,'P.E.',2),
(5,'DataBase',4),
(6,'OS',4),
(7,'C/C++',10);
/*往cs表中插入数据(安全插法)*/
INSERT INTO cs(s_no,c_no,cs_grade)
VALUES
('04161210',1,93),
('04161210',2,80),
('04161210',3,66),
('04161210',4,77),
('04161210',5,86),
('04161210',6,88),
('04161210',7,90),
('04161211',1,80),
('04161211',2,87),
('04161211',3,88),
('04161211',4,86),
('04161211',5,89),
('04161211',6,82),
('04161211',7,85),
('04161212',1,60),
('04161212',2,63),
('04161212',3,65),
('04161212',4,69),
('04161212',5,65),
('04161212',6,67),
('04161212',7,70),
('04161213',1,90),
('04161213',2,90),
('04161213',3,90),
('04161213',4,100),
('04161213',5,90),
('04161213',6,90),
('04161213',7,90),
('04161214',1,91),
('04161214',2,92),
('04161214',3,93),
('04161214',4,94),
('04161214',5,95),
('04161214',6,96),
('04161214',7,97),
('04161215',1,90),
('04161215',2,90),
('04161215',3,90),
('04161215',4,90),
('04161215',5,90),
('04161215',6,90),
('04161215',7,90);
SELECT *
FROM student;
SELECT *
FROM course;
SELECT *
FROM cs;
SELECT *
FROM XXX(表名);
/* 修改student表中数据 */
UPDATE student
SET s_name='黄超',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术(卓越)',s_class='计科1608'
WHERE s_no='04161210';
UPDATE student
SET s_name='王宇祥',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术(卓越)',s_class='计科1608'
WHERE s_no='04161210';
UPDATE student
SET s_name='朱宇',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161210';
UPDATE student
SET s_name='崔宇航',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161210';
UPDATE student
SET s_name='薛江伟',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161210';
UPDATE student
SET s_name='杨嘉亮',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161210';
UPDATE student
SET s_name='黄超',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术(卓越)',s_class='计科1608'
WHERE s_no='04161210';
UPDATE student
SET s_name='王宇祥',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术(卓越)',s_class='计科1608'
WHERE s_no='04161213';
UPDATE student
SET s_name='朱宇',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161211';
UPDATE student
SET s_name='崔宇航',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161214';
UPDATE student
SET s_name='薛江伟',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161215';
UPDATE student
SET s_name='杨嘉亮',s_sex='男',s_dept='计算机学院',s_major='计算机科学与技术',s_class='计科1607'
WHERE s_no='04161212';
/* 修改course表中数据 */
UPDATE course
SET c_name = '高等数学A'
WHERE c_no=1;
UPDATE course
SET c_name = '数据结构A'
WHERE c_no=2;
UPDATE course
SET c_name = '大学英语II'
WHERE c_no=3;
UPDATE course
SET c_name = '大学体育II'
WHERE c_no=4;
UPDATE course
SET c_name = '数据库原理及应用A'
WHERE c_no=5;
UPDATE course
SET c_name = '操作系统'
WHERE c_no=6;
//删除cs表中数据
DELETE FROM cs
WHERE c_no=1 AND s_no='04161210';
//删除整个表并重新创建(将表中数据全部清除)
TRUNCATE student;
TRUNCATE course;
TRUNCATE cs;
CREATE VIEW; //创建视图
SHOW CREATE VIEW viewname; //显示视图
DROP VIEW viewname; //删除视图
CREATE VIEW OR REPLACE VIEW; //创建或更新视图
//=============== 建立计算机学院全体学生各门课程的成绩表 ====================================================
CREATE VIEW CSCollStuGra AS
SELECT s_no,s_name,c_no,c_name,cs_grade
FROM cs,student,course
WHERE student.s_dept='CS' AND student.s_no=cs.s_no AND course.c_no=cs.c_no;
提示错误:ERROR 1052 (23000): Column 's_no' in field list is ambiguous
一般这个问题出现在多表查询中,这个是由于参数'sp_id' 存在多表中,没有声明是哪一个的参数,解决为:表名 . 参数
/*更改后*/
CREATE VIEW CSCollStuGra AS
SELECT student.s_no,student.s_name,course.c_no,course.c_name,cs.cs_grade
FROM cs,student,course
WHERE student.s_dept='CS' AND student.s_no=cs.s_no AND course.c_no=cs.c_no;
提示:Query OK, 0 rows affected (0.17 sec)
CREATE VIEW CSCollStuGra AS
SELECT student.s_no,student.s_name,course.c_no,course.c_name,cs.cs_grade
FROM cs,student,course
WHERE student.s_dept='计算机学院' AND student.s_no=cs.s_no AND course.c_no=cs.c_no;
SELECT *
FROM CSCollStuGra;
//在视图CSCollStuGra上查询4号课程的学生成绩并降序输出
SELECT s_no AS id,s_name AS name,c_name,cs_grade AS grade
FROM CSCollStuGra
WHERE c_no=4
ORDER BY cs_grade DESC;
/*更新视图需注意*/
更新一个视图将更新其基表
并非所有视图都是可更新的
1.分组(使用group by 和 having)
2.联结
3.子查询
4.并
5.聚集函数(min()、max()、sum()等)
6.distinct
7.导出(计算)列
视图为虚拟的表。它包含的不是数据而是根据需要检索数据的查询。
//安全管理
访问控制:数据库对不同的用户提供不同的操作手段使其仅能完成其所需的访问权限即可。
管理用户:mysql有一个名为user的表,它包含所有用户账号
创建用户账号:
CREATE USER ben IDENTIFIED BY 'p@$$w0rd';
重命名一个用户账号:
RENAME USER ben TO excalibur;
删除用户账号:
DROP USER excalibur;
设置访问权限:
查看赋予用户账号的权限:SHOW GRANTS FOR excalibur;
更改口令:SET PASSWORD FOR excalibur = Password('saber');
SET PASSWORD = Password('saber'); //在不指定用户名时,更改当前登录用户的口令
//数据库的维护
ANALYZE TABLE city; //检查表键是否正确
CHECK TABLE city; //针对多个问题对表进行检查
CHANGED //检查自最后一次检查以来改动过的表
EXTENDED //执行最彻底的检查
FAST //只检查未正常关闭的表
MEDIUM //检查所有被删除的链接并进行键检验
QUICK //只进行快速扫描
//方法1 嵌套
SELECT s_name
FROM student
WHERE s_no IN
(
SELECT s_no
FROM cs
WHERE cs_grade IN
(
SELECT cs_grade
FROM cs
WHERE cs_grade BETWEEN 90 AND 100
)
AND c_no=2
);
//方法2 多表连接
SELECT s_name
FROM student,cs
WHERE student.s_no = cs.s_no AND cs.c_no=2 AND cs.cs_grade BETWEEN 90 AND 100
ORDER BY s_name DESC;
/*AVG()用法:计算某门课(1号课)的平均成绩*/
SELECT AVG(cs_grade) AS avg_grade_1
FROM cs
WHERE c_no=1;
/*COUNT()用法1:统计有多少门课程(*不忽略列值为空的行)*/
SELECT COUNT(*) AS num_course
FROM course;
/*为实验用法2先修改表course*/
UPDATE course
SET c_credit = null
WHERE c_name = 'C/C++';
/*COUNT()用法2:统计表中有学分的课程数(忽略指定列值为空的行)*/
SELECT COUNT(c_credit) AS num_credit
FROM course;
/*用法2证明完恢复表course*/
UPDATE course
SET c_credit = 10
WHERE c_name = 'C/C++';
/*此时再查询有效学分课程为7*/
/*MAX()用法:查询1号课程的最高分*/
SELECT MAX(cs_grade) AS max_grade1
FROM cs
WHERE c_no=1;
/*MIN()用法:查询4号课程的最低分*/
SELECT MIN(cs_grade) AS min_grade4
FROM cs
WHERE c_no=4;
/*SUM()用法:计算4号课程总分*/
SELECT SUM(cs_grade) AS sum_grade4
FROM cs
WHERE c_no=4;
/*SUM()用法2:计算1号课程学分与学生总分之积*/
SELECT SUM(cs_grade*c_credit) AS creditMulgrade1
FROM cs,course
WHERE cs.c_no = 1 AND course.c_no = 1 ;
/*组合聚集函数 查询课程数量,最高学分,最低学分,平均学分*/
SELECT COUNT(*) AS num_course,
MIN(c_credit) AS min_credit,
MAX(c_credit) AS max_credit,
AVG(c_credit) AS avg_credit
FROM course;
/*创建分组:统计每门课程的选课人数*/
SELECT c_no,count(*) AS num_person
FROM cs
GROUP BY c_no;
/*为实验用法2先修改表CS*/
DELETE
FROM cs
WHERE c_no = 2 AND s_no = '04161210';
DELETE
FROM cs
WHERE c_no = 2 AND s_no = '04161211';
DELETE
FROM cs
WHERE c_no = 3 AND s_no = '04161212';
/*HAVING用法:统计选课人数小于等于5的课程号*/
SELECT c_no,count(*) AS num_person
FROM cs
GROUP BY c_no
HAVING COUNT(*)<=5;
/*恢复*/
INSERT INTO cs(s_no,c_no,cs_grade)
VALUES
('04161210',2,80),
('04161211',2,80),
('04161212',3,66);
/*CREATE TABLE S
{//大括号错误,改为下面的小括号
SNO CHAR(2) PRIMARY KEY,
SNAME CHAR(8),
STATUS INT,
CITY CHAR(8)
};*/
CREATE TABLE S
(
SNO CHAR(2) PRIMARY KEY,
SNAME CHAR(8),
STATUS INT,
CITY CHAR(8)
);
CREATE TABLE P
( PNO CHAR(2) PRIMARY KEY,
PNAME CHAR(8),
COLOR CHAR(2),
WEIGHT INT
);
CREATE TABLE J
(
JNO CHAR(2) PRIMARY KEY,
JNAME CHAR(8),
CITY CHAR(8)
);
CREATE TABLE SPJ
(
//SNO CHAR(2) PRIMARY KEY,报错多个主键被定义
//PNO CHAR(2) PRIMARY KEY,
//JNO CHAR(2) PRIMARY KEY,
SNO CHAR(2),
PNO CHAR(2),
JNO CHAR(2),
QTY INT,
//PRIMARY (SNO,PNO,JNO)是PRIMARY KEY而不是PRIMARY
PRIMARY KEY(SNO,PNO,JNO)
);
/*1.先看看表的结构*/
DESC S;
DESC P;
DESC J;
DESC SPJ;
/*2.完整后插入数据*/
/*错误用例
INSERT INTO S
VALUES SNO,SNAME,STATUS,CITY
(
('S1','精益',20,'天津'),
('S2','盛锡',10,'北京'),
('S3','东方红',30,'北京'),
('S4','丰泰盛',20,'天津'),
('S5','为民',30,'上海'),
);
*/
INSERT INTO S(SNO,SNAME,STATUS,CITY)
VALUES
('S1','精益',20,'天津'),
('S2','盛锡',10,'北京'),
('S3','东方红',30,'北京'),
('S4','丰泰盛',20,'天津'),
('S5','为民',30,'上海');
INSERT INTO P(PNO,PNAME,COLOR,WEIGHT)
VALUES
('P1','螺母','红',12),
('P2','螺栓','绿',17),
('P3','螺丝刀','蓝',14),
('P4','螺丝刀','红',14),
('P5','凸轮','蓝',40),
('P6','齿轮','红',30);
INSERT INTO J(JNO,JNAME,CITY)
VALUES
('J1','三建','北京'),
('J2','一汽','长春'),
('J3','弹簧厂','天津'),
('J4','造船厂','天津'),
('J5','机车厂','唐山'),
('J6','无线电厂','常州'),
('J7','半导体厂','南京');
INSERT INTO SPJ(SNO,PNO,JNO,QTY)
VALUES
('S1','P1','J1',200),
('S1','P1','J3',100),
('S1','P1','J4',700),
('S1','P2','J2',100),
('S2','P3','J1',400),
('S2','P3','J2',200),
('S2','P3','J4',500),
('S2','P3','J5',400),
('S2','P5','J1',400),
('S2','P5','J2',100),
('S3','P1','J1',200),
('S3','P3','J1',200),
('S4','P5','J1',100),
('S4','P6','J3',300),
('S4','P6','J4',200),
('S5','P2','J4',100),
('S5','P3','J1',200),
('S5','P6','J2',200),
('S5','P6','J4',500);
/*3.查看各表中数据*/
SELECT *
FROM S;
SELECT *
FROM P;
SELECT *
FROM J;
SELECT *
FROM SPJ;
SELECT DISTINCT SNO AS '供应工程J1零件的供应商号码SNO'
FROM SPJ
WHERE JNO = 'J1';
SELECT DISTINCT SNO AS '供应工程J1零件P1的供应商号码SNO'
FROM SPJ
WHERE JNO = 'J1' AND PNO = 'P1';
SELECT SNO AS '供应工程J1零件为红色的供应商号码SNO'
FROM SPJ,P
WHERE SPJ.JNO = 'J1' AND P.COLOR = '红' AND SPJ.PNO = P.PNO;
SELECT SNO AS '供应工程J1零件为红色的供应商号码SNO'
FROM SPJ
WHERE SPJ.JNO = 'J1' AND PNO IN(SELECT PNO FROM P WHERE COLOR = '红');
SELECT DISTINCT JNO AS '没有使用天津供应商生产的红色零件的工程号JNO'
FROM SPJ
WHERE JNO NOT IN
(
SELECT SPJ.JNO
FROM SPJ,S,P,J
WHERE S.CITY = '天津' AND P.COLOR = '红' AND SPJ.SNO = S.SNO AND SPJ.PNO = P.PNO
);
A.找出S1供应商供应的零件号
SELECT DISTINCT PNO AS 'S1供应商供应的零件号'
FROM SPJ
WHERE SNO='S1';
B.找出既使用了S1提供的P1又使用了S1提供的P2的工程号JNO
SELECT DISTINCT JNO AS '至少使用了供应商S1所提供的全部零件的工程号JNO'
FROM SPJ
WHERE SNO='S1' AND PNO='P1' AND JNO IN
(
SELECT JNO
FROM SPJ
WHERE SNO='S1' AND PNO='P2'
);
SELECT SNO AS '所有供应商的姓名',CITY AS '所在城市'
FROM S;
SELECT PNAME AS '所有零件的名称',COLOR AS '颜色',WEIGHT AS '重量'
FROM P;
SELECT JNO AS '使用供应商S1所供应零件的工程号码'
FROM SPJ
WHERE SNO='S1';
SELECT P.PNAME AS '工程项目J2使用的各种零件的名称',SPJ.QTY AS '数量'
FROM SPJ,P
WHERE SPJ.JNO='J2' AND SPJ.PNO=P.PNO;
SELECT DISTINCT PNO AS '上海厂商供应的所有零件号码'
FROM SPJ,S
WHERE SPJ.SNO=S.SNO AND S.CITY='上海';
SELECT DISTINCT JNO AS '使用上海产的零件的工程号码'
FROM SPJ,S
WHERE S.CITY='上海' AND SPJ.SNO = S.SNO;
SELECT DISTINCT JNO AS '没有使用天津产的零件的工程号码'
FROM SPJ,S
WHERE S.CITY<>'天津' AND SPJ.SNO = S.SNO;
UPDATE P
SET P.COLOR = '蓝'
WHERE P.COLOR = '红';
UPDATE SPJ
SET SNO = 'S3'
WHERE PNO = 'P6' AND SNO = 'S5' AND JNO = 'J4';
DELETE
FROM S,SPJ
WHERE SNO='S2';
DELETE
FROM S
WHERE S.SNO='S2';
DELETE
FROM SPJ
WHERE SPJ.SNO='S2';
INSERT INTO SPJ(SNO,PNO,JNO,QTY)
VALUES('S2','J6','P4',200);
DELIMITER //
CREATE PROCEDURE InsertInformations()
BEGIN
INSERT INTO course(c_no,c_name,c_credit)
VALUES(8,'计算机组成原理',6);
INSERT INTO course(c_no,c_name,c_credit)
VALUES(9,'编译原理',4);
INSERT INTO course(c_no,c_name,c_credit)
VALUES(10,'计算机网络',3);
END //
DELIMITER ;
CALL InsertInformations();
DROP PROCEDURE InsertInformations;
假设系统中有两个表:
班级表 class(班级号 classID, 班内学生数 stuCount)
学生表 student(学号 stuID, 所属班级号 classID)
要创建触发器来使班级表中的班内学生数随着学生的添加自动更新,代码如下:
DELIMITER $
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int;
set c = (select stuCount from class where classID=new.classID);
update class set stuCount = c + 1 where classID = new.classID;
end$
DELIMITER ;
MySQL 中使用 DECLARE 来定义一局部变量,该变量只能在 BEGIN … END 复合语句中使用,并且应该定义在复合语句的开头,
即其它语句之前,语法如下:
DECLARE var_name[,...] type [DEFAULT value]
其中:
var_name 为变量名称,同 SQL 语句一样,变量名不区分大小写;type 为 MySQL 支持的任何数据类型;可以同时定义多个同类型的变量,用逗号隔开;变量初始值为 NULL,如果需要,可以使用 DEFAULT 子句提供默认值,值可以被指定为一个表达式。
对变量赋值采用 SET 语句,语法为:
SET var_name = expr [,var_name = expr] ...
上述示例中使用了NEW关键字,和 MS SQL Server 中的 INSERTED 和 DELETED 类似,MySQL 中定义了 NEW 和 OLD,用来表示
触发器的所在表中,触发了触发器的那一行数据。
具体地:
在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;
在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;
使用方法: NEW.columnName (columnName 为相应数据表某一列名)
另外,OLD 是只读的,而 NEW 则可以在触发器中使用 SET 赋值,这样不会再次触发触发器,造成循环调用(如每插入一个学生前,都在其学号前加“2013”)。
和查看数据库(show databases;)查看表格(show tables;)一样,查看触发器的语法如下:
SHOW TRIGGERS [FROM schema_name];
其中,schema_name 即 Schema 的名称,在 MySQL 中 Schema 和 Database 是一样的,也就是说,可以指定数据库名,这样就
不必先“USE database_name;”了。
和删除数据库、删除表格一样,删除触发器的语法如下:
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失败,MySQL 会回滚事务,有:
①如果 BEFORE 触发器执行失败,SQL 无法正确执行。
②SQL 执行失败时,AFTER 型触发器不会触发。
③AFTER 类型的触发器执行失败,SQL 会回滚。