數據庫——SQL SERVER Transact-SQL 程序設計


什么是Transact-SQL?

標准SQL不支持過程化控制, 不能完成復雜的功能.
T-SQL是過程化SQL語言,   是SQL的擴展
增加了過程化語句 (變量,賦值,分支,循環...)
是數據庫服務器端的編程,不同於客戶端的應用程序
不是標准語言  (ORACLE中稱為PL/SQL)
作用:
編寫批處理、存儲過程,函數,觸發器

一 SQL-SERVER批處理

 

下面的示例創建兩個批處理。

USE STUDB          --這是使用STUDB數據庫
GO               

DECLARE @RS int                 /* 定義變量@RS */
SET   @RS =  (SELECT COUNT(*)         /* 變量賦值 */
      FROM STUDENT
      WHERE SDEPT='CS' )
PRINT '計科學院學生人數 ' + CAST(@RS AS char (3))
GO

 

用GO 命令結束一個批處理
兩種類型的注釋方式
一般保存到批處理文件中,以后打開執行,文件名后綴為.SQL

 

控制語句

 

BEGIN...END

BEGIN...END:一組要執行的 T-SQL 語句可以包含在 BEGIN...END 中。相當於C語言的復合語句{ }
 語法:

BEGIN 
 { 
  statement 
  | statement_block
 } 
END

 

其中,statement 為語句,statement_block 為語句塊。

 

IF...ELSE

IF...ELSE:可以根據指定的條件來執行不同的SQL 語句。

語法:

IF Boolean_expression 
    { sql_statement|statement_block } 
ELSE 
    { sql_statement|statement_block } 

IF 語句示例:

IFSELECT COUNT(*) FROM SC WHERE CNO=1 )>20--單值子查詢可以當做表達式
   BEGIN 
     ……
   END 
ELSE
   BEGIN 
     ……
   END

 

WHILE 循環

WHILE:可以根據某些條件來執行一條 SQL 語句或一組語句。只要指定的條件為真,則重復執行該語句。

語法:

WHILE Boolean_expression    
{ 
      statement | statement_block 
}   
      BREAK     
{ 
      statement | statement_block 
}   
     CONTINUE 

例題:
給1號課加分,如果平均分少於 75,每人加1分,如果最高分已經達到95,則停止加分 。

USE STUDB    
GO 
WHILE (SELECT AVG(GRADE) FROM SC WHERE CNO=1) < 75 --單值子查詢可以當做表達式
BEGIN                           --循環體用BEGIN END
  IF (SELECT MAX(grade) FROM SC WHERE CNO=1) >= 95  
      BREAK  
  UPDATE SC 
    SET GRADE=GRADE+1 WHERE CNO=1
END

PRINT '調整完成!'
GO

變量

兩種類型的變量:                
全局變量
    全局變量是SQL Server系統內部使用的變量,任何程序均可調用。
局部變量
  自定義變量, 作用於局部

 

全局變量:


 

SQL Server 中的全局變量都用'@@' 標記作為前綴。

可以使用PRINT 輸出全局變量的值。

 

輸出SQL SERVER版本

PRINT @@VERSION

輸出上一個SQL語句影響的行數

SELECT * FROM SC WHERE CNO=1 
PRINT  @@ROWCOUNT 

局部變量:

局部變量名必須以 '@' 為前綴, 先定義,再使用。用DECLARE定義, 類型同表的列類型。

作用域:聲明局部變量的批處理、存儲過程或語句塊。

DECLARE   @姓名         CHAR(20)
DECLARE   @年齡         INT
DECLARE   @工資         FLOAT
DECLARE   @地址         VARCHAR(40)
DECLARE   @SNO         NUMERIC(5), @SNAME   CHAR(6),  @SAGE    INT

注意:變量的初值為空值null !

兩種方法為變量賦值

SET 語句或 SELECT 語句用於給局部變量賦值。

DECLARE @姓名  CHAR(10), @年齡 INT
SET @姓名 ='劉晨'     --SET一次只能賦值一個變量
--賦值單值子查詢結果
SET @姓名 = (SELECT SNAME FROM STUDENT WHERE SNO=95001)

或:

 
         
DECLARE @姓名 CHAR(10), @年齡 INT
SELECT
@姓名 ='劉晨',@年齡=20 --SELECT可多 賦值 --賦值單值查詢結果 SELECT @姓名 = SNAME, @年齡=SAGE
FROM STUDENT
WHERE SNO=95001

 

注意這里給賦值單值子查詢SET SELECT的區別,SELECT已經有了一個SELECT所以可以省去不寫,但SET必須寫,否則會報錯!!

SET @CCOURSE =( SELECT COUNT(*) FROM   SC WHERE SNO=@SNO )--SET必須寫SELECT
SELECT @AVG =(SELECT AVG(GRADE) FROM SC WHERE SNO=@SNO) 
SELECT @AVG = AVG(GRADE) 
FROM SC
WHERE SNO=@SNO --SELECT可以省去不寫

 

局部變量的使用實例:

DECLARE @姓名  CHAR(10)
SET @姓名 ='劉晨'
SELECT *  FROM STUDENT 
    WHERE SNAME=@姓名--變量可以用在SQL語句中
GO

變量值的輸出

格式一:單表達式輸出
功能:一次只能輸出一個局部變量值或一個表達式的值。
例句:

print @x+4
print @y


格式二: 多表達式輸出
功能:一次可輸出若干個局部變量值或表達式的值。按查詢表的格式輸出,一般不用。
例句:

select @x, @y+100

 

T-SQL語法總結

變量定義:     DECLARE  @變量名  類型
變量賦值:     SET @變量=表達式
             SET @變量=( 單值子查詢 )
             SELECT @變量1=表達式1,@變量2=表達式2
             SELECT @變量1=列1,@變量2=列2  FROMWHERE 條件
輸出:        PRINT ‘輸出結果是’+CAST( @變量名  AS  CHAR(3))
條件:        IF  條件表達式
                 語句          /*多條語句要用BEGIN  END*/
             ELSE
                 語句          /*多條語句要用BEGIN  END*/
循環:        WHILE   條件表達式
             BEGIN
                  語句
             END 

二   SQL-SERVER 存儲過程

什么是存儲過程?

存儲過程(procedure)類似於C語言中的函數
存儲過程可以帶參數。

void  sum(int a,int b)
{  
   int s;
   s =a+b;
   printf("sum=%d\n", s) ;
}

存儲過程的分類

系統存儲過程
由系統定義,存放在master數據庫中,類似C語言中的系統函數,系統存儲過程的名稱都以“sp_”開頭

用戶自定義存儲過程
由用戶在自己的數據庫中創建的存儲過程,經編譯和優化后存儲在數據庫服務器中,使用時只要調用即可。類似C語言中的用戶自定義函數。

常用的系統存儲過程:

如何創建存儲過程?

創建存儲過程的語法

CREATE  PROCEDURE  存儲過程名 [參數]
AS
   SQL語句
GO


執行存儲過程的語法

EXEC  存儲過程名  [參數]

 

建立存儲過程, 顯示計科學院的學生人數:

CREATE  PROCEDURE  CSCOUNT 
    AS
DECLARE @RS int                 /* 定義變量@RS */
SET   @RS =  (SELECT COUNT(*)         /* 變量賦值 */
      FROM STUDENT
      WHERE SDEPT='CS' )
PRINT '計科學院學生人數 ' + CAST(@RS AS char (3))
GO

執行存儲過程語句:

EXEC  CSCOUNT

 

創建不帶參數的存儲過程

問題:計算機等級考試分為筆試成績和機試成績,
    請創建存儲過程,查看本次考試平均分以及未通過考試的學員名單
需要定義什么變量?  

CREATE PROCEDURE proc_stu   --proc_stu為自定義的存儲過程名
  AS
    DECLARE @writtenAvg float,@labAvg float
    SELECT @writtenAvg=AVG(writtenExam),
           @labAvg=AVG(labExam)  FROM Marks
    print '筆試平均分:'+CAST(@writtenAvg AS CHAR(3))  
    print '機試平均分:'+CAST(@labAvg AS CHAR(3))
    IF (@writtenAvg>70 AND @labAvg>70) --顯示考試成績的等級 
       print '本班考試成績:優秀'
    ELSE
       print '本班考試成績:較差'
    print '--------------------------------------------------'
    print '           參加本次考試沒有通過的學員:'
    SELECT stuName,stu.stuNo,writtenExam,labExam--顯示未通過的學員
    FROM  stu, Marks
    WHERE stu.stuNo=Marks.stuNo AND (writtenExam<60 OR labExam<60)
GO

調用存儲過程

EXEC    PROC_STU

 

 

 

帶輸入參數的存儲過程

CREATE  PROCEDURE  DEPTCOUNT 
    @DEPT  CHAR(2)     /* 參數變量 注意位置  無關鍵字DECLARE*/
AS
DECLARE @RS int                 /* 定義變量@RS */
SET   @RS =  (SELECT COUNT(*)         /* 變量賦值 */
      FROM STUDENT
      WHERE SDEPT=@DEPT )
PRINT @DEPT+'學院學生人數 ' + CAST(@RS AS char (3))
GO

執行存儲過程語句:

EXEC  DEPTCOUNT   'CS' 

 

練習: 建立過程 PSTU, 輸出某學生的姓名和總學分.
過程參數?    變量?   代碼?

DROP PROCEDURE PSTU
GO
CREATE PROCEDURE PSTU 
@SNO INT
  AS
    DECLARE @NAME CHAR(20)
    DECLARE @TOTAL INT
    SELECT @NAME=SNAME FROM STUDENT WHERE SNO=@SNO
    SELECT @TOTAL=SUM(CCREDIT) FROM COURSE,SC
    WHERE SC.SNO=@SNO AND SC.CNO=COURSE.CNO
    PRINT'Name='+@NAME+'Total credit='+CAST(@TOTAL AS CHAR(3))
GO

如何執行?

EXEC   PSTU  95001

 

練習:
建立過程 PSTU2, 輸出某學生的姓名, 選課門數, 平均分, 最高分,最低分, 總學分, 如果總學分<9,則顯示“此學生學分不足!”,否則顯示“此學生學分已足!”,

過程參數?    變量?   代碼?

 

DROP PROCEDURE PSTU2
GO

CREATE PROCEDURE PSTU2
@SNO INT
  AS
    DECLARE @NAME CHAR(20),@CCOURSE INT,@TOTAL INT,@AVG INT
    SELECT @NAME=SNAME FROM STUDENT WHERE SNO=@SNO
    SELECT @CCOURSE =COUNT(*) FROM   SC WHERE SNO=@SNO 
    SELECT @TOTAL= SUM(CCREDIT) FROM COURSE,SC WHERE SC.SNO=@SNO AND SC.CNO=COURSE.CNO
    SELECT @AVG = AVG(GRADE) FROM SC WHERE SNO=@SNO 
    PRINT'Name='+@NAME+    '選課門數'+CAST(@CCOURSE AS CHAR(5))+'平均分'
    +CAST(@AVG AS CHAR(5))+'Total credit='+CAST(@TOTAL AS CHAR(3))
    IF(@TOTAL<9)
    PRINT '此學生學分不足!'
    ELSE
    PRINT '此學生學分已足!'
GO

如何執行?
    EXEC   PSTU2  95001

 

 

總結  

存儲過程是一組預編譯的SQL語句,它可以包含數據操縱語句、變量、邏輯控制語句等
定義存儲過程的語法:
  

CREATE  PROCEDURE  存儲過程名
    @參數1  數據類型,
     …… ,
    @參數n  數據類型
 AS
     SQL語句
 GO


EXECUTE(執行,調用)存儲過程的語法:

 EXEC  過程名  [參數]

 

存儲過程的優點

經編譯和優化后存儲在數據庫服務器中,運行效率高
客戶端應用程序可以調用
降低客戶機和服務器之間的通信量
有利於集中控制,方便維護

三 SQL-SERVER 游標

什么是游標?

先看一個例子:
   設計一個存儲過程,參數是課號,顯示某門課的優、良、中、及格、差的人數。

輸出某門課優良差人數 實現方法1

CREATE PROCEDURE P1  
@CNO INT    --參數為課號
AS
DECLARE @優 int,@良 int,@差 int
SET  @優=( SELECT COUNT(*) FROM SC WHERE CNO=@CNO AND GRADE>=90 )
SET   @良=( SELECT COUNT(*) FROM SC WHERE CNO=@CNO AND GRADE>=80 AND GRADE<90 )
SET   @差=( SELECT COUNT(*) FROM SC WHERE CNO=@CNO AND GRADE<80 )
PRINT '優人數'+CAST(@優 AS CHAR(2))+' 良人數'+CAST(@良 AS CHAR(2)) +' 差人數'+CAST(@差  AS CHAR(2))
GO

多遍掃描SC, 效率低

 

游標(cursor)

SQL查詢結果是記錄的集合
可將SQL語句的查詢結果定義為游標,游標代表一個查詢結果集合
可以逐一從游標中獲取記錄,進行處理。

游標操作分為四步:
          1、聲明游標:
            DECLARE 游標名 CURSOR FOR
                 SELECT查詢
           2、打開游標
           3、循環從游標中提取數據
           4、關閉游標

 

輸出某門課優良差人數 實現方法2,使用游標:
將選某門課的成績(這是一個查詢)定義為一個游標,對游標中的成績循環判斷,統計

DROP PROCEDURE P1
GO

CREATE PROCEDURE P1  
@CNO INT 
AS
DECLARE @成績 int,@優 int,@良 int,@差 int
DECLARE C1 CURSOR FOR        /*定義游標*/
       SELECT GRADE FROM SC WHERE CNO=@CNO
SELECT  @優=0,@良=0,@差=0     /*計數變量清零(原初值為null) */
OPEN C1      /*打開游標—執行游標中的SELECT*/
WHILE  1=1                 --建立循環
BEGIN                         --循環體開始
  FETCH NEXT FROM C1 INTO @成績     /*讀游標*/
  
  IF @@fetch_status<>0   /*判斷提取結束*/
          BREAK  
  IF @成績 IS NOT NULL
     IF @成績 >=90 
        SET @優=@優+1
     ELSE IF @成績 >=80    
        SET @良=@良+1
     ELSE 
        SET @差=@差+1
END                                     --循環體結束
CLOSE C1  /*關閉游標*/
DEALLOCATE C1  /*釋放游標*/
PRINT '優人數'+CAST(@優 AS CHAR(2))+' 良人數'+CAST(@良 AS CHAR(2)) +' 差人數'+CAST(@差  AS CHAR(2))
GO

 

游標語法框架:

/*定義有關變量*/
DECLARE 游標名 CURSOR FOR        /*(1)定義游標*/
        SELECT子查詢
OPEN   游標名                     /*(2)打開游標—執行游標中的SELECT*/
WHILE  1=1                 --建立循環
BEGIN                         --循環體開始
  /*(3)讀游標的一行到變量, 變量的個數類型要與游標中子查詢一致  */
  FETCH NEXT FROM 游標名 INTO @變量1@變量2
  IF @@fetch_status<>0   /*判斷提取結束*/
          BREAK  
  處理   
END                              --循環體結束
CLOSE  游標名      /*(4)關閉游標*/
DEALLOCATE  游標名       /*釋放游標*/

 

練習:

使用游標, 統計輸出男生人數,女生人數,年齡>20的人數,年齡<=20的人數。

CREATE PROCEDURE P2  
AS
--定義變量存放男生人數,女生人數,年齡>20的人數,年齡<=20的人數
--定義變量存放性別,年齡
DECLARE C1 CURSOR FOR        /*定義游標*/
       SELECT SSEX,SAGE FROM STUDENT
 ......

DROP PROCEDURE P2  
GO

CREATE PROCEDURE P2  
AS
DECLARE @MC INT,@WC INT,@UP INT,@DOWN INT
DECLARE @SSEX CHAR(2),@AGE INT
SELECT @MC=0,@WC=0,@UP=0,@DOWN=0
DECLARE C1 CURSOR FOR       
SELECT SSEX,SAGE FROM STUDENT
OPEN C1     
WHILE  1=1                 
BEGIN                         
  FETCH NEXT FROM C1 INTO @SSEX,@AGE  
  
  IF @@fetch_status<>0   
          BREAK  
  IF @SSEX IS NOT NULL
     IF @SSEX ='' 
        SET @MC=@MC+1
     ELSE IF @SSEX=''    
        SET @WC=@WC+1
   IF @AGE IS NOT NULL
     IF @AGE >20
        SET @UP=@UP+1
     ELSE IF @AGE<=20   
        SET @DOWN=@DOWN+1
END                                 
CLOSE C1  /*關閉游標*/
DEALLOCATE C1  /*釋放游標*/
PRINT '男生人數'+CAST(@MC AS CHAR(2))+'女生人數'+CAST(@WC AS CHAR(2)) 
+ '年齡>20的人數'+ CAST(@UP  AS CHAR(2))+ '年齡<=20的人數'+CAST(@DOWN  AS CHAR(2))
GO

 

 

 

 

思考題:

使用游標, 統計每門課的課名,成績前三名的學生名。
定義幾個游標?什么游標?
定義什么變量?
如何處理?

 

DROP PROCEDURE P3
GO

CREATE PROCEDURE P3 
@CNO INT
AS
DECLARE @SNO INT,@SNAME CHAR(20),@SDEPT CHAR(5),@GRADE INT
DECLARE @COUNT INT
DECLARE C1 CURSOR FOR      
SELECT STUDENT.SNO,SNAME,SDEPT,GRADE 
FROM STUDENT,SC
WHERE STUDENT.SNO=SC.SNO AND @CNO=SC.CNO
ORDER BY GRADE DESC
SET @COUNT=0
OPEN C1     
WHILE  1=1                 
BEGIN                         
  FETCH NEXT FROM C1 INTO @SNO,@SNAME,@SDEPT,@GRADE
  IF @@fetch_status<>0   
      BREAK  
  IF @COUNT=3
      BREAK
  SET @COUNT=@COUNT+1
  PRINT '學號'+CAST(@SNO AS CHAR(10))+'姓名'+@SNAME+ '系名'
  + @SDEPT+ '成績'+CAST(@GRADE  AS CHAR(5))
END                                 
CLOSE C1  
DEALLOCATE C1  
GO

 

 

四 SQL-SERVER 觸發器

WHAT IS TRIGGER?

觸發器是一種特殊的存儲過程,它不能被顯式地調用,
而是在往表中插入記錄、更改記錄或者刪除記錄時,才被自動地調用。

SQL-SERVER觸發器的類型

對每個表, 可以建立
DELETE 觸發器
INSERT 觸發器
UPDATE 觸發器

創建觸發器的語法:

CREATE TRIGGER 觸發器名
 ON  表名
 FOR [DELETE, INSERT, UPDATE]
 AS 
  T-SQL語句
GO

DELETE, INSERT, UPDATE指定觸發器的類型

兩個臨時表:  INSERTED 和DELETED

觸發器觸發時,系統自動在內存中創建兩個臨時表:   INSERTED和DELETED
INSERTED 表臨時保存了新記錄行(插入或更新后的記錄行)  
DELETED 表臨時保存了舊記錄行(刪除或更新前的記錄行)
結構與觸發器對應表相同
觸發器執行完成后,自動刪除這兩個表
只讀,用於檢查操作是否滿足業務需求

 

查看DELETED, INSERTED內容

編寫觸發器, 當選課表修改數據時, 顯示修改前后的數據


編寫觸發器:
    哪個表?
    哪種觸發語句?
    修改前的行,修改后的行存放在哪里?

CREATE TRIGGER trig_SC
    ON  SC                        
FOR UPDATE    AS         --SC表的UPDATE觸發器
      SELECT   * FROM deleted  --deleted存舊數據   
      SELECT * FROM inserted  -- inserted存新數據
GO 

 

UPDATE觸發器  

編寫觸發器, 使學生的年齡修改只能增1

編寫觸發器:
    哪個表?
    哪種觸發語句?
    修改前的行,修改后的行存放在哪里?
    修改前的年齡? 修改后的年齡?

-----使學生的年齡修改只能增1----
DROP TRIGGER trig_update_sage    --為防止重建時報錯, 先刪一下
GO
CREATE TRIGGER trig_update_sage
ON STUDENT                        
FOR UPDATE    AS         --STUDENT表的UPDATE觸發器
      DECLARE @beforeSage int,@afterSage int    --定義變量  
      SET @beforeSage=(SELECT TOP 1 SAGE FROM deleted)  --舊數據   
      SET @afterSage=(SELECT TOP 1 SAGE FROM inserted)  -- 新數據
      IF @afterSage-@beforeSage<>1 AND @afterSage-@beforeSage<>0
        BEGIN
            PRINT ‘年齡修改只能增1’     --報錯  
            ROLLBACK TRANSACTION --回滾,撤銷引起觸發器的UPDATE語句
        END
GO 

 

DELETE觸發器

編寫觸發器, 在deletedsc中記錄SC表刪除的行 (deletedsc表已建立, 結構同SC)

編寫觸發器:
    哪個表?
    哪種觸發語句?
    刪除的行存放在哪里?

-------關鍵代碼------
CREATE TRIGGER trig_delete_SC
 ON SC
  FOR DELETE 
   AS
     INSERT INTO DELETEDSC   SELECT * FROM deleted
 
GO 

 

INSERT觸發器---實時統計

實時統計:在學生表中增加選課門數列CCOUNT和總成績列GTOTAL
CREATE TABLE STUDENT
(SNO  NUMERIC(5)  CONSTRAINT P_STUDENT PRIMARY KEY,
。。。。。。
        CCOUNT NUMERIC(3),        --選課門數
        GTOTAL NUMERIC(5)          --總成績
);
編寫SC的插入、刪除和修改觸發器, 自動更新學生表中選課門數和總成績.

-------關鍵代碼------
--當插入SC數據時,自動更新學生表中選課門數列和總成績列.
CREATE TRIGGER trig_insert_sc
ON  SC
FOR insert    AS
      DECLARE @GRADE INT, @SNO INT   
      /* 從INSERTED中取插入的學號和成績  */
      SELECT   @SNO=SNO,@GRADE=GRADE FROM INSERTED   
      IF @GRADE IS NOT NULL
         UPDATE STUDENT
             SET CCOUNT=CCOUNT+1,  GTOTAL=GTOTAL+@GRADE
             WHERE SNO=@SNO    
GO 

 

DELETE觸發器 ---實時統計

DELETE可能刪除多行
要對刪除的多行逐行進行處理
如何進行?

CREATE TRIGGER trig_delete_sc ON  SC
FOR DELETE    AS                                 --SC表DELETE觸發器
      DECLARE @sno int ,@grade int    --定義變量
      DECLARE C1 CURSOR FOR          --定義游標,存放被刪的數據 
           SELECT SNO,GRADE FROM  DELETED
     OPEN C1                                           --打開游標 
     WHILE  1=1                                       --循環
     BEGIN 
         FETCH NEXT FROM C1 INTO  @SNO, @GRADE  --讀游標
         IF @@fetch_status<>0                  --如果讀完了
             BREAK  
         IF @GRADE IS NOT NULL
             UPDATE STUDENT     
SET CCOUNT=CCOUNT-1,GTOTAL=GTOTAL-@GRADE
WHERE SNO=@sno END CLOSE C1 DEALLOCATE C1 GO

 

當對SC表UPDATE時,如何自動更新學生表中選課門數列和總成績列?

對SC表建立UPDATE觸發器
UPDATE可能修改多行
修改前的數據,修改后的數據?
要對修改的多行進行處理,如何進行?

 

/*建立兩個游標C1,C2,分別對應 deleted inserted*/
/*循環處理游標,發現修改,同步更新STUDENT*/
DROP TRIGGER trig_update_sc    
GO
 CREATE TRIGGER trig_update_sc ON SC
 FOR UPDATE AS
 DECLARE @sno1 int,@grade1 int
 DECLARE @sno2 int,@grade2 int
 DECLARE C1 CURSOR FOR
 SELECT SNO,GRADE FROM deleted
 DECLARE C2 CURSOR FOR
 SELECT SNO,GRADE FROM inserted
 OPEN C1
 OPEN C2
 WHILE 1=1
 BEGIN
 FETCH NEXT FROM C1 INTO @SNO1,@GRADE1 
 FETCH NEXT FROM C2 INTO @SNO2,@GRADE2 
 IF @@fetch_status<>0
    BREAK
 
 IF @SNO1=@SNO2/*學號未變*/
 BEGIN
     IF @GRADE1 IS NOT NULL AND @GRADE2 IS NOT NULL AND @GRADE1<>@GRADE2/*更新前后均不為空*/
        UPDATE STUDENT
        SET GTOTAL=GTOTAL-@GRADE1+@GRADE2 
        WHERE SNO=@sno1
     ELSE IF @GRADE1 IS NULL AND @GRADE2 IS NOT NULL/*更新前為空,更新后不為空*/
        UPDATE STUDENT
        SET CCOUNT=CCOUNT+1,
        GTOTAL=GTOTAL+@GRADE2
        WHERE SNO=@sno1
     ELSE IF @GRADE1 IS NOT NULL AND @GRADE2 IS NULL/*更新前不為空,更新后為空*/
        UPDATE STUDENT
        SET CCOUNT=CCOUNT-1,
        GTOTAL=GTOTAL-@GRADE1
        WHERE SNO=@sno1
 END

ELSE/*學號變了*/
BEGIN
    IF @GRADE1 IS NOT NULL/*對舊學號相當於刪選課*/
       UPDATE STUDENT 
       SET CCOUNT=CCOUNT-1,GTOTAL=GTOTAL-@GRADE1 
       WHERE SNO=@sno1
    IF @GRADE2 IS NOT NULL/*對新學號相當於插入選課*/
       UPDATE STUDENT 
       SET CCOUNT=CCOUNT+1,GTOTAL=GTOTAL+@GRADE2 
       WHERE SNO=@sno2
 END
 END/*where*/
 CLOSE C1
 CLOSE C2
 DEALLOCATE C1
 DEALLOCATE C2
 GO

 

查看觸發器信息

觸發器作為一種特殊的存儲過程,在用戶創建以后,其名字存放在系統表sysobjects中,其創建源代碼存放在syscomments系統表中。
查看指定表中所定義的觸發器及它們的類型:
    EXEC sp_helptrigger  表名
查看指定觸發器的定義文本:
    EXEC sp_helptext  觸發器名
刪除觸發器:
    DROP TRIGGER   觸發器名

 

總結

觸發器是在對表進行插入、更新或刪除操作時自動執行的存儲過程
觸發器作用: 增強數據完整性和安全性,實時統計
觸發器一般都需要使用臨時表:deleted表和inserted表,它們存放了被刪除或插入的記錄行副本
創建觸發器的語法:

 CREATE TRIGGER 觸發器名
    ON  表名
    FOR [DELETE, INSERT, UPDATE]
 AS 
    T-SQL語句
 GO

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM