SQL的综合案例(触发器、函数、游标、存储过程)

下面是一个学生信息的创建
在这里就不创建数据库了

CREATE TABLE CLASS
(
    class_id    int IDENTITY PRIMARY KEY,   --班级ID
    class_name  Varchar(50),    --班级名称
    class_studentCount  Int --班级的学生数量
)
GO
CREATE TABLE STUDENT
(
    stu_id  int IDENTITY PRIMARY KEY,--学生ID
    stu_name    Varchar(50) ,--学生姓名
    class_id    Int ,--班级ID
    AvgScore    float   DEFAULT 0--学生的平均成绩,默认为0
)
GO
CREATE TABLE SCORE 
(
    Score_ID    int IDENTITY PRIMARY KEY,--分数ID
    stu_id  Varchar(50),--  学生ID
    courseName  Varchar(50),--  科目名称
    score   float     ,--学生成绩
)

下面是对数据的操作:

–提示语句:为学生表创建触发器:实现当添加一条学生信息时班级表中的学生数量加1

CREATE TRIGGER T_STUDENTINSERT
ON STUDENT --关于某个表的触发器
AFTER INSERT --在添加学生之后触发该触发器
AS
BEGIN
    UPDATE DBO.CLASS SET CLASS_STUDENTCOUNT = CLASS_STUDENTCOUNT +1 WHERE CLASS_ID IN (SELECT CLASS_ID FROM INSERTED)
END

对代码的分析:
看到提示语句:你会肿么做嘞!
1.首先分析提示语句:可以看到要创建一个触发器这是毋庸置疑的
CREATE TRIGGER T_STUDENTINSERT
2.其次:创建触发器肯定是基于某个表上的 那么提示语已经告诉我们了 没错是学生表
ON STUDENT
3.接下来是:看在何种情况下要触发该触发器 在添加一个语句 时 改变班级中相应的人数
AFTER INSERT
4.最后要看的就是执行什么语句了:触发以后执行的就是更改相应的班级人数
BEGIN
UPDATE DBO.CLASS SET CLASS_STUDENTCOUNT = CLASS_STUDENTCOUNT +1 WHERE CLASS_ID IN (SELECT CLASS_ID FROM INSERTED)
END
那么这条语句又是什么意思?一起来研究一下:
1).首先时更新数据基于的时班级表中的人数
2).然后就是对数据更新必须的时条件 那就是ID
ID从哪里来的呢?
在添加数据生成的数据中的CALSS_ID 与之匹配
最后让班级人数自增

–提示语句:为学生表创建触发器:实现当修改学生表class_id时,print 出如下信息:‘警告:xx同学已经转到xx班级,请知晓!’

CREATE TRIGGER T_STUDENTUPDATE
ON STUDENT
AFTER UPDATE 
AS
BEGIN
    DECLARE @STU_NAME NVARCHAR(50)
    DECLARE @CLASS_NAME NVARCHAR(50)

    SELECT @STU_NAME = stu_name FROM inserted
    SELECT @CLASS_NAME=CLASS_NAME FROM DBO.CLASS WHERE class_id IN (SELECT class_id FROM inserted)
    PRINT '警告:'+@STUNAME+'同学已经转到'+@CLASS_NAMEF+'班级,请知晓!'
    --'警告:'+@STUNAME+'同学已经转到'+@CLASS_NAMEF+'班级,请知晓!'
END             

代码分析:

1.首先分析提示语句:可以看到要创建一个触发器这是毋庸置疑的
            CREATE TRIGGER T_STUDENTUPDATE
2.其次:创建触发器肯定是基于某个表上的 那么提示语已经告诉我们了 没错是学生表
            ON STUDENT
3.接下来是:看在何种情况下要触发该触发器 :实现当修改 时 
            AFTER UPDATE 
4.最后要看的就是执行什么语句了:触发以后执行的 print 出如下信息:‘警告:xx同学已经转到xx班级,请知晓!’

            BEGIN
                DECLARE @STU_NAME NVARCHAR(50)--定义变量来接受改变的学生姓名
                DECLARE @CLASS_NAME NVARCHAR(50) --定义变量来接受改变的班级
                SELECT @STU_NAME = stu_name FROM inserted 
                SELECT @CLASS_NAME=CLASS_NAME FROM DBO.CLASS WHERE class_id IN (SELECT class_id FROM inserted)
                PRINT '警告:'+@STUNAME+'同学已经转到'+@CLASS_NAMEF+'班级,请知晓!'

            END

提示语句:
写一个标值函数 fun_GetSoreRank:
–1) .定义 Score输入参数, 返回 varchar(50)类型

–2) 在函数中使用 case when then end 实现:根据传入的分数值进行等级判断,并返回相应的等级字符串,等级规则如下:
–成绩小于60分:不及格;60-70:及格;70-80:中等;80-100:优秀; 100:满分

CREATE FUNCTION FUN_GETSORERANK(@SCORE INT)
RETURNS NVARCHAR(20)
BEGIN
    DECLARE @NAME NVARCHAR(50)
    SELECT @NAME= (CASE WHEN @SCORE <60 THEN '不及格' WHEN @SCORE>=60 AND @SCORE<=70 THEN '及格' WHEN @SCORE>70 AND @SCORE<=80 THEN '中等' WHEN @SCORE>80 AND @SCORE<100 THEN '优秀' WHEN @SCORE = 100 THEN '满分' END)

RETURN @NAME 
END

代码分析:
创建一个标值函数 函数中的参数和类型
CREATE FUNCTION FUN_GETSORERANK(@SCORE INT)

返回的类型 此函数中返回的参数类型为NVARCHAR(50)
RETURNS NVARCHAR(20)
函数中要执行的语句为:根据不同的成绩来定义不同的学生的等级 返回数据

BEGIN
DECLARE @NAME NVARCHAR(50)
SELECT @NAME= (CASE WHEN @SCORE <60 THEN ‘不及格’ WHEN @SCORE>=60 AND @SCORE<=70 THEN ‘及格’ WHEN @SCORE>70 AND @SCORE<=80 THEN ‘中等’ WHEN @SCORE>80 AND @SCORE<100 THEN ‘优秀’ WHEN @SCORE = 100 THEN ‘满分’ END)

RETURN @NAME
END

提示语句:编写一个视图v_getSutdentScore,查询出 学生名称、班级名称、考试科目、成绩分数、成绩等级(调用fun_GetSoreRank函数)

CREATE VIEW V_GETSTUDENTSCORE
AS

SELECT S.stu_name,C.class_name,SC.courseName,SC.score ,DBO.FUN_GETSORERANK(SC.score) AS '等级' FROM CLASS C JOIN STUDENT S ON C.class_id = S.class_id JOIN SCORE SC ON SC.stu_id = S.stu_id

提示语句:编写一个存储过程 p_UpdateSutdentAvgSocre,实现批量统计某班级下每个学生的平均成绩并修改学生表中每个学生的平均分(AvgScore):
–1) 正确的创建存储过程,并定义输入参数classID
–2) 正确的定义、打开、关闭游标
–3) 正确的使用while 进行循环逐行读取
–4) 正确的判断游标的读取状态
–5) 实现使用游标逐行统计该班每个学生的平均成绩,并修改学生表的AvgScore字段

CREATE PROC P_UPDATESTUDENTAVGSOCRE
@CLASSID INT
AS
BEGIN
    DECLARE CURSOR_STUDENT CURSOR SCROLL FOR SELECT STU_ID,AVGSCORE FROM DBO.STUDENT --定义游标数据集
    OPEN CURSOR_STUDENT --打开游标
    DECLARE @STU_ID INT
    DECLARE @AVGSCORE INT
    FETCH FIRST FROM CURSOR_STUDENT INTO @STU_ID,@AVGSCORE 
    DECLARE @AVG FLOAT
    --循环第一条记录
    WHILE(@@FETCH_STATUS = 0)
    BEGIN
        SELECT @AVG = AVG(SCORE) FROM DBO.SCORE
        UPDATE DBO.STUDENT SET AvgScore=@AVG WHERE stu_id = @STU_ID 
        FETCH NEXT FROM CURSOR_STUDENT INTO @STU_ID,@AVGSCORE -- 接着循环数据
    END
    CLOSE CURSOR_STUDENT --关闭游标
    DEALLOCATE CURSOR_STUDENT--删除释放资源
END

看到此博文的博友们:
你们有没有发现一个问题?对于SQL语句来说,就像做数学题一样,在给的提示中充分利用每一个条件(有些条件是不会明着说的,在这里也就是隐含的条件),再利用你所学的所有知识,就可以看到你想要看到的结果。你觉得呢?
如果有什么不对的地方,还请大佬们指出。谢谢!!!

猜你喜欢

转载自blog.csdn.net/Writing_the_future/article/details/82745459