觸發器sql
觸發器的基礎知識數據庫
create trigger tr_name on table/view {for | after | instead of } [update][,][insert][,][delete] [with encryption] as {batch | if update (col_name) [{and|or} update (col_name)] }
說明:
1 tr_name :觸發器名稱
2 on table/view :觸發器所做用的表。一個觸發器只能做用於一個表
3 for 和after :同義
4 after 與instead of :sql 2000新增項目afrer 與 instead of 的區別
After
在觸發事件發生之後才被激活,只能夠創建在表上
Instead of
代替了相應的觸發事件而被執行,既能夠創建在表上也能夠創建在視圖上
5 insert、update、delete:激活觸發器的三種操做,能夠同時執行,也可選其一
6 if update (col_name):代表所做的操做對指定列是否有影響,有影響,則激活觸發器。此外,由於delete 操做只對行有影響,
因此若是使用delete操做就不能用這條語句了(雖然使用也不出錯,可是不能激活觸發器,沒意義)。
7 觸發器執行時用到的兩個特殊表:deleted ,inserted
deleted 和inserted 能夠說是一種特殊的臨時表,是在進行激活觸發器時由系統自動生成的,其結構與觸發器做用的表結構是同樣的,只是存放 的數據有差別。
8 說明deleted 與inserted 數據的差別
deleted 與inserted 數據的差別
Inserted 存放進行insert和update 操做後的數據
Deleted 存放進行delete 和update操做前的數據
注意:update 操做至關於先進行delete 再進行insert ,因此在進行update操做時,修改前的數據拷貝一條到deleted 表中,修改後的數據在存到觸發器做用的表的同時,也同時生成一條拷貝到insered表中編程
觸發器典型示例安全
if exists(select name from sysobjects where xtype='tr' and name='tri_updateStudent') begin drop trigger tri_UpdateStudent end go create trigger tri_UpdateStudent on dbo.student for update as if update(Sage) begin update student set sage=s.sage+d.sage from student s,deleted d where s.studentid=d.studentid end go
存儲過程網絡
存儲過程的優勢 ide
A、 存儲過程容許標準組件式編程函數
B、 存儲過程可以實現較快的執行速度spa
C、 存儲過程減輕網絡流量日誌
D、 存儲過程可被做爲一種安全機制來充分利用code
存儲過程的實例
if exists(select * from sysobjects where xtype='p' and name='proc_Student') begin drop proc proc_student end go create proc proc_Student @name varchar(255), @age varchar(255) as begin tran select * from student where sname=@name and sage=@age if @@ERROR<>0 begin rollback tran insert into student(studentid,sname,sage) values (1,@name,@age) return 0 end else begin commit tran select * from student end go exec proc_student '程興亮',1;
表變量
表變量定義:
表變量建立的語法相似於臨時表,區別就在於建立的時候,必需要爲之命名。表變量是變量的一種,表變量也分爲本地及全局的兩種,本地表變量的名稱都是以「@」爲前綴,只有在本地當前的用戶鏈接中才能夠訪問。全局的表變量的名稱都是以「@@」爲前綴,通常都是系統的全局變量,像咱們經常使用到的,如@@Error表明錯誤的號,@@RowCount表明影響的行數。
DECLARE @News table ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime ) INSERT INTO @News (News_id, NewsTitle, NewsContent, NewsDateTime) VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE()) SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM @News
臨時表
臨時表定義:
臨時表與永久表類似,只是它的建立是在Tempdb中,它只有在一個數據庫鏈接結束後或者由SQL命令DROP掉,纔會消失,不然就會一直存在。臨時表在建立的時候都會產生SQL Server的系統日誌,雖它們在Tempdb中體現,是分配在內存中的,它們也支持物理的磁盤,但用戶在指定的磁盤裏看不到文件。
臨時表分爲本地和全局兩種,本地臨時表的名稱都是以「#」爲前綴,只有在本地當前的用戶鏈接中才是可見的,當用戶從實例斷開鏈接時被刪除。全局臨時表的名稱都是以「##」爲前綴,建立後對任何用戶都是可見的,當全部引用該表的用戶斷開鏈接時被刪除
CREATE TABLE dbo.#News ( News_id int NOT NULL, NewsTitle varchar(100), NewsContent varchar(2000), NewsDateTime datetime ) INSERT INTO dbo.#News (News_id, NewsTitle, NewsContent, NewsDateTime) VALUES (1,'BlueGreen', 'Austen', 200801, GETDATE()) SELECT News_id, NewsTitle, NewsContent, NewsDateTime FROM dbo.#News DROP TABLE dbo.[#News]
表變量和臨時表對比總結
特性 |
表變量 |
臨時表 |
做用域 |
當前批處理 |
當前會話,嵌套存儲過程,全局:全部會話 |
使用場景 |
自定義函數,存儲過程,批處理 |
自定義函數,存儲過程,批處理 |
建立方式 |
DECLARE statement only.只能經過DECLEARE語句建立 |
CREATE TABLE 語句 SELECT INTO 語句. |
表名長度 |
最多128字節 |
最多116字節 |
列類型 |
可使用自定義數據類型 可使用XML集合 |
自定義數據類型和XML集合必須在TempDb內定義 |
Collation |
字符串排序規則繼承自當前數據庫 |
字符串排序規則繼承自TempDb數據庫 |
索引 |
索引必須在表定義時創建 |
索引能夠在表建立後創建 |
約束 |
PRIMARY KEY, UNIQUE, NULL, CHECK約束可使用,但必須在表創建時聲明 |
PRIMARY KEY, UNIQUE, NULL, CHECK. 約束可使用,能夠在任什麼時候後添加,但不能有外鍵約束 |
表創建後使用DDL (索引,列) |
不容許 |
容許. |
數據插入方式 |
INSERT 語句 (SQL 2000: 不能使用INSERT/EXEC). |
INSERT 語句, 包括 INSERT/EXEC. SELECT INTO 語句. |
Insert explicit values into identity columns (SET IDENTITY_INSERT). |
不支持SET IDENTITY_INSERT語句 |
支持SET IDENTITY_INSERT語句 |
Truncate table |
不容許 |
容許 |
析構方式 |
批處理結束後自動析構 |
顯式調用 DROP TABLE 語句. |
事務 |
只會在更新表的時候有事務,持續時間比臨時表短 |
正常的事務長度,比表變量長 |
存儲過程重編譯 |
否 |
會致使重編譯 |
回滾 |
不會被回滾影響 |
會被回滾影響 |
統計數據 |
不建立統計數據,因此全部的估計行數都爲1,因此生成執行計劃會不精準 |
建立統計數據,經過實際的行數生成執行計劃。 |
做爲參數傳入存儲過程 |
僅僅在SQL Server2008, 而且必須預約義 user-defined table type. |
不容許 |
顯式命名對象 (索引, 約束). |
不容許 |
容許,可是要注意多用戶的問題 |
動態SQL |
必須在動態SQL中定義表變量 |
能夠在調用動態SQL以前定義臨時表 |
用法:無表關聯操做,只做爲中間集進行數據處理,建議用表變量;有表關聯,且不能肯定數據量大小的狀況下,建議用臨時表。