sql插入觸發器
『壹』 有關sql insert觸發器和update觸發器
DML觸發器有三類:
1, insert觸發器;
2, update觸發器;
3, delete觸發器;
觸發器的組成部分:
觸發器的聲明,指定觸發器定時,事件,表名以類型
觸發器的執行,PL/SQL塊或對過程的調用
觸發器的限制條件,通過where子句實現
類型:
應用程序觸發器,前台開發工具提供的;
資料庫觸發器,定義在資料庫內部由某種條件引發;分為:
DML觸發器;
資料庫級觸發器;
替代觸發器;
DML觸發器組件:
1,觸發器定時
2,觸發器事件
3,表名
4, 觸發器類型
5, When子句
6, 觸發器主體
可創建觸發器的對象:資料庫表,資料庫視圖,用戶模式,資料庫實例
創建DML觸發器:
Create [or replace] trigger [模式.]觸發器名
Before| after insert|delete|(update of 列名)
On 表名
[for each row]
When 條件
PL/SQL塊
For each row的意義是:在一次操作表的語句中,每操作成功一行就會觸發一次;不寫的話,表示是表級觸發器,則無論操作多少行,都只觸發一次;
When條件的出現說明了,在DML操作的時候也許一定會觸發觸發器,但是觸發器不一定會做實際的工作,比如when 後的條件不為真的時候,觸發器只是簡單地跳過了PL/SQL塊;
Insert觸發器的創建:
create or replace trigger tg_insert
before insert on student
begin
dbms_output.put_line('insert trigger is chufa le .....');
end;
/
執行的效果:
SQL> insert into student
2 values(202,'dongqian','f');
insert trigger is chufa le .....
update表級觸發器的例子:
create or replace trigger tg_updatestudent
after update on student
begin
dbms_output.put_line('update trigger is chufale .....');
end;
/
運行效果:
SQL> update student set se='f';
update trigger is chufale .....
已更新8行;
可見,表級觸發器在更新了多行的情況下,只觸發了一次;
如果在after update on student後加上
For each row的話就成為行級觸發器,運行效果:
SQL> update student set se='m';
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
update trigger is chufale .....
已更新8行;
:new 與: old:必須是針對行級觸發器的,也就是說要使用這兩個變數的觸發器一定有for each row
這兩個變數是系統自動提供的數組變數,:new用來記錄新插入的值,old用來記錄被刪除的值;
使用insert的時候只有:new里有值;
使用delete的時候只有:old里有值;
使用update的時候:new和:old里都有值;
可以這樣使用: dbms_output.put_line('insert trigger is chufa
dbms_output.put_line('new id is : '||:new.stui
dbms_output.put_line('new name is : '||:new.st
dbms_output.put_line('new se is : '||:new.se);
可以這樣從數據字典中查看一個表上有哪幾個觸發器:
SQL> select trigger_name from user_triggers
2 where table_name=upper('student');
TRIGGER_NAME
------------------------------
TG_INSERT
TG_UPDATESTUDENT
帶有:old變數的行級delete觸發器:
create or replace trigger tg_deletestudent
before delete on student
for each row
begin
dbms_output.put_line('old is: '||:old.stuid);
dbms_output.put_line('old name: '||:old.stuname);
end;
/
運行效果:
SQL> delete from student;
old is: 202
old name: dongqian
old is: 101
old name: liudehua
old is: 102
old name: lingqingxia
old is: 103
old name: lichanggong
old is: 104
old name: zhenxiuwen
old is: 1001
old name: lilianjie
old is: 1009
old name: tongleifuck
old is: 203
old name: kfdj
old is: 209
old name: fuck
已刪除9行
When的使用:如果在begin也就是說觸發器的PL/SQL主體塊執行前加上when(old.se=』f』)的話,DML操作照做不誤,但是只會在刪除
Se=』f』的那行的時候才會執行觸發器的主體動作,執行效果:
SQL> delete from student;
old is: 209
old name: fuck
已刪除9行; 這里雖然刪了9行,但是只執行了一次觸發器的主體,做為一個行級觸發器;
混合類型觸發器:
Inserting,deleting,updating三個謂詞可以分別指示當前操作到底是哪個;
create or replace trigger hunhetrigger
before insert or update or delete on student
for each row
begin
if inserting then
dbms_output.put_line('insert le.........');
end if;
if deleting then
dbms_output.put_line('delete le .......');
end if;
end;
/
插入的時候就自動判斷當前動作為插入:
SQL> insert into student values(303,'me','f');
insert le.........
刪除的時候就自動判斷當前動作為刪除:
SQL> delete from student;
delete le .......
注意,既然觸發器內部的主體PL/SQL是語句,那麼它同樣也可以是插入刪除操作而不一定只是dbms_output列印一些信息;
這正是日誌表的原理:在用戶執行了DML語句的時候觸發主體為插入日誌表以記錄操作軌跡的觸發器;
為什麼用觸發器? 當我們有兩個表用來記錄商品的出庫入庫情況,good_store用來記錄庫存的產品類別和數量,
而good_out用來記錄出庫的產品類別和數量,那麼每當我們出庫的某個類別的產品一定數量的時候,我們應該在good_out中插入該產品的類別和
出庫數量,而同時也應該在good_store表中用update來更新庫存的相應類別的產品的數量;這就交給了我們兩個必須完成的任務:插入good_out
表後更新good_store表,這樣的手工過程使得我們覺得非常ugly,如果只做其中一個那造成數據的不一致;所以現在我們可以用觸發器,在
Good_out表的插入操作上綁定一個對good_store進行更新的觸發器;當然這個過程應該是一個事務,你不必擔心插入good_out表執行了,而綁定在這個動作上的觸發器操作不會執行,相信Oracle設計為原子性了;
注意:觸發器會使得原來的SQL語句速度變慢;
替代觸發器:
創建在視圖上的觸發器,就是替代觸發器,只能是行級觸發器;
為什麼要用替代觸發器?
假如你有一個視圖是基於多個表的欄位連接查詢得到的;現在如果你想直接對著這個視圖insert;那你一定在想,我對視圖的插入操作
怎麼來反應到組成這個視圖的各個表中呢?事實上,除了定義一個觸發器來綁定在對視圖上的插入動作上外,你沒有別的辦法通過系統的報錯而直接向視圖中插入數據;這就是我們用替代觸發器的原因;替換的意思實際上是觸發器的主體部分把對視圖的插入操作轉換成詳細的對各個表的插入;
變異表:變異表就是當前SQL語句正在修改的表,所以在一個變異表上綁定的觸發器不可以使用cout()函數,原因很簡單:SQL語句剛剛修改了表,你怎麼統計??
約束表:
維護:
Alter trigger …..disenable; 使得觸發器不可用;
Alter trigger ……enable; 開啟觸發器;
Oracle的內置程序包
擴展資料庫的功能;
為PL/SQL提供對SQL功能的訪問;
一般具有sys許可權的高級管理人員使用;
一個典型的程序包就是dbms_output,你老是用它的過程put_line();
Dbms_standard 提供語言工具;
Dbms_lob操作Oracle LOB;就是針對大型數據的操作設計的;
Dbms_lock用戶定義的鎖;
Dbms_job 允許對PL/SQL過程進行調度;
Dbms_alert 支持資料庫事件的非同步通知;
1,dbms_output的一些過程:
a):enable
b):disable
c):put只是把數據放到緩存(SQL-Plus的緩存,實際就是整個窗口)中,無輸出功能;
d):put_line可以使得以前放在緩存中所有數據輸出;並且換到下一行;
e):new_line
f):get_line
g):get_lines
2,dmbs_lob ,這個包只能是由系統管理員來操作;
Clob以字元數據存儲可達2G;
Blob以二進制數據存儲可達4G;
Nclob以unicode字元存儲;
一個文件下載列表的例子:
創建下載目錄表:
create table downfilelist
(
id varchar(20) not null primary key,
name varchar(40) not null,
filelocation bfile,
description clob
)
/
創建目錄:
create or replace directory filedir as 'f:\oracle'
/只是向Oralce注冊了目錄,實際上並不會真的建立目錄在磁碟上;Oracle無權管理和鎖定操作系統的文件系統;
向目錄表中插入數據:
insert into downfilelist
values('10001','oracle plsal編程指南',bfilename(upper('filedir'),'demo.mp3'),'this is a mp3 music')
insert into downfilelist
values('10002','java 大權', bfilename(upper('filedir'),'x.jpg'),'good super girl')
/在filedir的目錄f:\oracle下實際存儲著demo.mp3 ,x.jpg;
注意,如果你試圖查詢,效果是 :
sys>select * from downfilelist;
SP2-0678: 列或屬性類型無法通過 SQL*Plus 顯示
因為第三列是無法顯示的,是一個二進制的;
下面使用dbms_lob的一些過程來進行操作:
1,read過程
declare
tempdesc clob;
ireadcount int;
istart int;
soutputdesc varchar(100);
begin
ireadcount:=5;
istart:=1;
select description into tempdesc from downfilelist where id='10001';
dbms_lob.read(tempdesc,ireadcount,istart,soutputdesc); 把clob類型的tempdesc中的數據讀到字元類型的soutputdesc里;
dbms_output.put_line('Top 5 character is: '||soutputdesc);
end;
/注意,對unicode來說,漢字和字母所佔的位數是一樣的;
2,getlength函數
select description into tempclob from downfilelist where id=『10001』;
ilen:=dbms_lob.GetLength(tempclob);
append,……..
發現這樣的現象:select x into y的時候,y並不是獨立於x的拷貝,因為當修改y的時候x也被修改了;
3, fileexists函數
select id ,dbms_lob.fileexists(filelocation) from downfilelist;
如果在bfile類型欄位filelocation指定的系統下的目錄中存在filelocation指定的系統文件,則返回int 1,否則返回0;
這說明Oracle還是可以檢測到系統的文件情況的,如同java.io包里的類一樣;
對bfile類型數據的操作函數有fileisopen,fileopen,fileclose等等;
如果對您有幫助,請記得採納為滿意答案,謝謝!祝您生活愉快!
vaela
『貳』 SQl中觸發器怎樣執行的
創建觸發器 是特殊的存儲過程,自動執行,一般不要有返回值。
1、後觸發器 (AFTER,FOR)先執行對應語句,後執行觸發器中的語句。
2、前觸發器 並沒有真正的執行觸發語句(insert,update,delete),而是執行觸發後的語句。
3、行級觸發器 (FOR EACH ROW) 在SQL server 中不存在。
(2)sql插入觸發器擴展閱讀:
創建觸發的語法
CREATE TRIGGER trigger_name --觸發器名稱
ON table_name --觸發的表
[WITH ENCRYPTION]
FOR [DELETE, INSERT, UPDATE] --選擇觸發器類型
AS --觸發後要做的語句
T-SQL語句
GO --結束標記
『叄』 sql插入觸發器使得有成績錄入時課程表中的選課人數自動加一
摘要 create or replace trigger aaa
『肆』 sql 增加 觸發器
drop TRIGGER if EXISTS insert_data;
create trigger insert_data
after INSERT on a
for each ROW
BEGIN
insert into b select * from a order by id desc limit 1;
end;
a表的id設置自增,每次插入數據的時候獲取a表最新一條id,插入到B表,親測有效
『伍』 sql插入一條語句觸發器
/* 如果存在同名的觸發器,則刪除之* /
IF EXISTS ( SELECT name FROM sysobjects
WHERE type = 『 TR『 AND name = 'student_insert' )
DROP TRIGGER student_insert
GO
/*建立新的觸發器(在向表中插入數據時觸發)*/
CREATE TRIGGER student_insert ON student
FOR INSERT
AS
/*聲明觸發器運行時要用到的變數*/
DECLARE @NumOfStudent TINYINT
/%將插入記錄的那個班級的學生總數賦給上面的變數%/
SELECT @NumOfStudent = c.student_num FROM class c ,inserted i
WHERE c.class_id = i.class_id
IF (@NumOfStudent > 0)/*如果class_id這個班級的學生總數不是0個*/
BEGIN
/*將班級學生總數+1*/
UPDATE class SET student_num = student_num + 1
FROM class c ,inserted i WHERE c.class_id = i.class_id
END
ELSE /*否則,統計一下student表中,屬於class_id的學生數,並賦給班級表中的student_num欄位*/
BEGIN
UPDATE class SET student_num = (
SELECT COUNT(s.student_id) FROM student s ,inserted i
WHERE s.class_id = i.class_id)
FROM class c, inserted i WHERE c.class_id = i.class_id
END
GO
『陸』 SQL insert觸發器問題
你用的for insert 肯定是不行的
在你執行觸發器檢測之前,sql就已經插入數據到你的資料庫中去了
解決方案有兩種
1 是不用觸發器,自己在插入數據之前手動進行檢測,如果存在,則不在插入
2 把for insert改成 instead of insert
sql中的前置觸發器是instead of,這種觸發器在數據更新前發生
但要注意,在檢查數據通過後,要在該觸發器中重發更新語句,否則不會發生更新動作.
就是說
if exists(select * from Client where ClientName=@ClientName)
begin
rollback tran
raiserror('該客戶名已存在,請重新輸入客戶名!',16,1)
end
這里還要改 改成
if exists(select * from Client where ClientName=@ClientName)
begin
rollback tran
raiserror('該客戶名已存在,請重新輸入客戶名!',16,1)
end
else
insert into Client ...(你的插入語句)
總的說來 第一方法簡單些,而且性能相對來說好一些
『柒』 求SQL插入觸發器語句
這個其實不是很難,其sql語句為;
create trigger a_trigger
on TB2
for insert
as
begin
update TB1 set b=b+1 from inserted,TB1 where inserted.a=TB1.a
end
經過在sql 2005/sql 2008完美通過測試!
『捌』 SQL Server Insert觸發器
年齡+1歲是指他們本來有年齡數據了么?如果有,那麼一條更新語句應該行,不需要觸發器。update
student
set
sage=sage+1
如果是插入數據時想把原來的年齡+1則需要觸發器
set
ansi_nulls
on
set
quoted_identifier
on
go
alter
trigger
[dbo].[add]
on
student]
after
insert
as
begin
set
nocount
on;
update
student
set
sage=sage+1
end
默認成績均為0是不需要觸發器的,你把grade欄位的默認值設為0即可。
『玖』 sql插入觸發器問題
觸發器是在插入之後觸發的,也就是說不管你觸發器裡面寫什麼肯定都是先插了再說(霸王硬上弓?)
然後其次,觸發器裡面的內容是判斷選課人數是否大於180,大於的話就輸入選課人數已滿,那麼下次別人就不能選課了,但是觸發的這次是插入功成功的
『拾』 SQL求助 插入刪除修改的觸發器代碼編寫
---創建測試表:
Create Table MyTest(
id int identity(1,1) not null primary key,
[name] varchar(100) null
)
--創建觸發器:
CREATE TRIGGER trigtest--創建觸發器trigtest
ON mytest--在表mytest上建
for INSERT,DELETE,UPDATE--為插入,刪除,修改
AS
BEGIN
declare @a int,
@b int,
@id int,
@name varchar(100),
@oldId int,--原ID號
@oldName varchar(100)--原來的name
set @a=0
set @b=0
if exists(select * from inserted)--如果存在插入新的數據則設置@a=1
begin
set @a=1
end
if exists(select * from deleted)--如果存在刪除數據則設置@b=1
begin
set @b=1
end
if (@a=1)and(@b=0)--新增:當插入表inserted存在數據而刪除表deleted不存數據時,為新增操作。
begin
select @id=id,@name=name from inserted
print '增加了ID號為【'+cast(@id as varchar(5))+'】Name為【'+@name+'】的數據!'
end
if (@a=1)and(@b=1)--修改:當插入表insertedt和刪除表deleted都存在數據時,為修改操作。
begin
select @id=id,@name=name from inserted
select @id=id,@oldname=name from deleted
print '修改了ID號為【'+cast(@id as varchar(5))+'】的數據Name由【'+@oldname+'】變為【'+@name+'】'
end
if (@a=0)and(@b=1)--刪除:當插入表inserted不存在數據而刪除表deleted存在數據時,為刪除操作。
begin
select @id=id,@name=name from deleted
print '刪除了ID號為【'+cast(@id as varchar(5))+'】Name為【'+@name+'】的數據!'
end
END