实验的SQL
触发器
DDL
- 设置一个触发器,当对student表某位学生进行更新时,限制学生年龄必须超过18,否则报错“学生年龄应该大于18”。
CREATE TRIGGER UP_STUDENT
ON STUDENT
FOR UPDATE
AS
BEGIN
DECLARE @SAGE INT;
SELECT @SAGE = SAGE FROM INSERTED;
IF @SAGE <= 18
BEGIN
RAISERROR('学生年龄应该大于18', 16, 1);
ROLLBACK TRANSACTION;
END
END;
UPDATE STUDENT SET SAGE=17 WHERE SNO='98003'
- 设置一个针对course表的插入触发器,当插入课程记录, 学分Ccredit这项为空时,设定为1。
CREATE TRIGGER INS_COURSE
ON COURSE
FOR INSERT
AS
BEGIN
DECLARE @CNO CHAR(2), @CCREDIT INT;
SELECT @CNO = CNO, @CCREDIT = CCREDIT FROM INSERTED;
IF (@CCREDIT IS NULL)
UPDATE COURSE SET CCREDIT = 1 WHERE CNO = @CNO;
END;
INSERT INTO COURSE (CNO, CNAME, CCREDIT, CTEACHER)
VALUES ('8', 'c语言B', '6', NULL);
SELECT * FROM COURSE WHERE CNO = '8';
- 对course创建一个一次只删除一条记录的触发器,否则报错“此删除操作可能会删除多门课程数据!!!”
CREATE TRIGGER del_course
ON course
FOR DELETE
AS
BEGIN
DECLARE @row_cnt INT;
SELECT @row_cnt = COUNT(*) FROM deleted;
IF @row_cnt > 1
BEGIN
RAISERROR('此删除操作可能会删除多门课程数据!!!', 16, 1);
ROLLBACK TRANSACTION;
END;
END;
DELETE FROM course
WHERE ccredit = 4;
- 级联更新:当修改student表中sno列的值时,同时修改sc表中的sno列的值,并且一次只能更新一行。
CREATE TRIGGER student_update1
ON student
FOR UPDATE
AS
BEGIN
DECLARE @row_cnt INT;
SELECT @row_cnt = COUNT(*) FROM deleted;
IF @row_cnt > 1
BEGIN
RAISERROR('此删除操作可能会修改多位学生数据!!!', 16, 1);
ROLLBACK TRANSACTION;
END
ELSE
BEGIN
IF UPDATE(sno)
BEGIN
DECLARE @OLDSNO CHAR(5), @NEWSNO CHAR(5);
SELECT @OLDSNO = SNO FROM DELETED;
SELECT @NEWSNO = SNO FROM INSERTED;
UPDATE sc SET sno = @NEWSNO WHERE sno = @OLDSNO;
END
END
END;
①第一种更新多行:
UPDATE student SET sage = sage + 1;
②第二种更新单行,完成级联更新:
UPDATE student SET sno = '08001' WHERE sno = '98001';
- 创建触发器,当插入某个同学选课成绩时,如果他所在系是CS,其成绩自动加5分。
CREATE TRIGGER sc_insert ON SC
FOR INSERT
AS
BEGIN
DECLARE @SNO CHAR(5), @CNO CHAR(2), @SDEPT CHAR(2);
SELECT @SNO = SNO, @CNO = CNO FROM INSERTED;
SELECT @SDEPT = SDEPT FROM STUDENT WHERE SNO = @SNO;
IF (@SDEPT = 'CS')
BEGIN
UPDATE SC SET GRADE = GRADE + 5 WHERE SNO = @SNO AND CNO = @CNO;
END;
END;
INSERT INTO SC VALUES('98002', '6' ,80);
SELECT * FROM SC WHERE SNO='98002' AND CNO='5';
- 为SC表建立一个更新触发器updateSC,当修改SC中某门课程的成绩时自动输出此门课程的平均成绩。
CREATE TRIGGER updateSC
ON SC
FOR UPDATE
AS
BEGIN
DECLARE @AVERAGE INT;
SELECT @AVERAGE = AVG(SC.GRADE) FROM SC, INSERTED WHERE SC.CNO = INSERTED.CNO;
PRINT @AVERAGE;
END;
SELECT * FROM SC WHERE CNO = '2';
SELECT AVG(GRADE) FROM SC WHERE CNO = '2';
UPDATE SC SET GRADE = GRADE * 0.7 WHERE CNO = '2';
- 为SC表建立一个插入触发器insertSC,当向SC表插入一条选课记录后自动统计输出该学生所选课程的门数。
CREATE TRIGGER insertSC
ON SC
FOR INSERT
AS
BEGIN
DECLARE @num INT;
SELECT @num = COUNT(SC.CNO) FROM SC, INSERTED WHERE SC.SNO = INSERTED.SNO;
PRINT @num;
END;
SELECT * FROM SC WHERE SNO = '98002';
SELECT COUNT(CNO) FROM SC WHERE SNO = '98002';
INSERT INTO SC VALUES('98002', '7', 72);
存储过程
- 利用存储过程,给student表添加一位学生信息。
-- 定义存储过程
CREATE PROCEDURE pro_ins_student
@sno CHAR(5),
@sname VARCHAR(20),
@sage SMALLINT,
@ssex CHAR(2),
@sdept CHAR(2)
AS
BEGIN
-- 插入学生信息到 student 表
INSERT INTO student VALUES (@sno, @sname, @sage, @ssex, @sdept)
END
-- 执行存储过程,插入学生信息
EXEC pro_ins_student '98005', '王二', 20, '女', 'CS'
-- 验证插入结果,查询 student 表
SELECT * FROM student WHERE sno = '98005'
(2)利用存储过程查找王林同学所选课程的课程名称、学分和成绩。
-- 定义
CREATE PROCEDURE cname_sname
@sname VARCHAR(20)
AS
BEGIN
SELECT course.cname, course.ccredit, sc.grade
FROM student, sc, course
WHERE student.sno = sc.sno
AND sc.cno = course.cno
AND sname LIKE @sname;
END
-- 执行
EXEC cname_sname '王林';
(3)利用存储过程返回‘2’号课程的平均成绩。
-- 定义
CREATE PROCEDURE cno_gradeave
@cno CHAR(2),
@grade_ave NUMERIC(6, 2) OUTPUT
AS
BEGIN
SELECT @grade_ave = AVG(grade)
FROM sc
WHERE cno = @cno;
END
-- 执行
DECLARE @ave_grade NUMERIC(6, 2);
EXEC cno_gradeave '2', @ave_grade OUTPUT;
SELECT @ave_grade;
(4)利用存储过程从sc表中返回课程的课程号和最高分。
-- 定义
CREATE PROCEDURE max_course
AS
BEGIN
SELECT cno, MAX(grade)
FROM sc
GROUP BY cno;
END
-- 执行
EXEC max_course;
(5)利用存储过程,通过游标方式获取某个给定学号(如‘98001’学生)的最高成绩。
-- 定义
CREATE PROCEDURE pro_sno
@sno CHAR(5)
AS
BEGIN
DECLARE @grade INT, @max INT;
SET @max = -1;
DECLARE get_grade CURSOR FOR
SELECT grade
FROM sc
WHERE sno = @sno;
OPEN get_grade;
FETCH get_grade INTO @grade;
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF @grade IS NOT NULL
BEGIN
IF @grade > @max
SET @max = @grade;
END;
FETCH get_grade INTO @grade;
END;
CLOSE get_grade;
DEALLOCATE get_grade;
IF @max = -1
PRINT '该学生未选课或者未参加过考试';
ELSE
SELECT @max;
END
-- 执行
EXEC pro_sno '98001';
(6)创建存储过程,通过游标扫描学生选课表中某同学的成绩,如果该学生的成绩小于60分,则把该同学该门课程选课记录删除。
-- 定义
CREATE PROCEDURE Pro_delete_grade
@sno CHAR(5)
AS
BEGIN
DECLARE @grade INT;
DECLARE cur_grade CURSOR FOR
SELECT grade
FROM sc
WHERE sno = @sno;
OPEN cur_grade;
FETCH cur_grade INTO @grade;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @grade < 60
BEGIN
DELETE FROM sc
WHERE CURRENT OF cur_grade;
END;
FETCH cur_grade INTO @grade;
END;
CLOSE cur_grade;
DEALLOCATE cur_grade;
END
-- 执行
EXEC Pro_delete_grade '98001';
-- 验证是否进行了删除
SELECT * FROM sc WHERE sno = '98001';
授权(直接与间接)
可以通过直接和间接的方式授权权限给用户或角色。下面是授权权限的示例:
- 直接授权权限:
GRANT 权限1, 权限2, ...
ON 对象名
TO 用户名或角色名
示例:
GRANT SELECT, INSERT
ON Customers
TO UserA
上述语句直接将 SELECT 和 INSERT 权限授予了 UserA 用户,使其可以在 Customers 表上执行这些操作。
- 间接授权权限:
GRANT 角色名
TO 用户名
示例:
GRANT SalesRole
TO UserA
上述语句将 SalesRole 角色授予了 UserA 用户。然后,在 SalesRole 角色上授予的权限将间接应用于 UserA 用户。
创建表
- 创建一个简单的表:
CREATE TABLE Customers (
CustomerID INT,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Email VARCHAR(100)
)
- 创建一个带有主键的表:
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT,
OrderDate DATE,
TotalAmount DECIMAL(10, 2)
)
- 创建一个带有外键关系的表:
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50)
)
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT,
OrderDate DATE,
TotalAmount DECIMAL(10, 2),
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
)
- 创建一个带有自增长列的表:
CREATE TABLE Products (
ProductID INT IDENTITY(1,1) PRIMARY KEY,
ProductName VARCHAR(100),
Price DECIMAL(10, 2),
Quantity INT
)
- 创建一个带有默认约束的表:
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Gender CHAR(1) DEFAULT 'M',
DateOfBirth DATE
)
- 创建一个包含检查约束的表:
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Age INT CHECK (Age >= 18),
Grade CHAR(2)
)
以上是六个建表语句的例子,每个例子都使用了不同的约束和数据类型来展示不同的功能和用法。
以下为出现过的sql
CREATE TABLE STUDENT (
SNO CHAR(5) PRIMARY KEY,
SNAME VARCHAR(20),
SAGE SMALLINT CHECK (SAGE >= 15 AND SAGE <= 45),
SSEX CHAR(2) DEFAULT '男' CHECK (SSEX = '男' OR SSEX = '女'),
SDEPT CHAR(2)
);
CREATE TABLE COURSE (
CNO CHAR(2) PRIMARY KEY,
CNAME VARCHAR(20),
CPNO CHAR(2),
CCREDIT SMALLINT
);
CREATE TABLE SC (
SNO CHAR(5) NOT NULL,
CNO CHAR(2) NOT NULL,
GRADE SMALLINT CHECK ((GRADE IS NULL) OR (GRADE BETWEEN 0 AND 100)),
PRIMARY KEY (SNO, CNO),
FOREIGN KEY (SNO) REFERENCES STUDENT (SNO),
FOREIGN KEY (CNO) REFERENCES COURSE (CNO)
);