1. 程式人生 > >SQL的綜合案例(觸發器、函式、遊標、儲存過程)

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 '警告:'[email protected]+'同學已經轉到'[email protected]_NAMEF+'班級,請知曉!'
    --'警告:'[email protected]+'同學已經轉到'[email protected]_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 '警告:'[email protected]+'同學已經轉到'[email protected]_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 [email protected]AVG WHERE stu_id = @STU_ID 
        FETCH NEXT FROM CURSOR_STUDENT INTO @STU_ID,@AVGSCORE -- 接著迴圈資料
    END
    CLOSE CURSOR_STUDENT --關閉遊標
    DEALLOCATE CURSOR_STUDENT--刪除釋放資源
END

看到此博文的博友們:
你們有沒有發現一個問題?對於SQL語句來說,就像做數學題一樣,在給的提示中充分利用每一個條件(有些條件是不會明著說的,在這裡也就是隱含的條件),再利用你所學的所有知識,就可以看到你想要看到的結果。你覺得呢?
如果有什麼不對的地方,還請大佬們指出。謝謝!!!