起因:有乙個組表,是樹型結構,結構如下:
create table cfg_team(
team_id int,
team_name varchar(50),
paths varcahr(4000), --根據當前層次自動計算更新
parent_id int)
這個paths有點類似檔案目錄的意思,是父級節點paths+'.'+本級節點id,當父級節點id為0時,paths=''
還有一種情況是當某個有子節點的節點變更父節點時,該節點的paths和所有子節點的paths都要依次變更(相當於把乙個資料夾移動位置)
paths主要目的是查詢時可以用like,而且不需要使用 with cte遞迴。
資料表結果舉例:
insert into cfg_team values (1, 'a', '', 0)
insert into cfg_team values (2, 'aa', '1.2', 1)
insert into cfg_team values (3, 'ab', '1.3', 1)
insert into cfg_team values (4, 'aaa', '1.2.4', 2)
insert into cfg_team values (5, 'b', '', 0)
insert into cfg_team values (6, 'ba', '5.6', 5)
insert into cfg_team values (7, 'aaaa', '1.2.4.7', 4)
insert into cfg_team values (8, 'aaaaa', '1.2.4.7.8', 7)
insert into cfg_team values (9, 'aaaaaa', '1.2.4.7.8.9', 8)
問題:如何更新這個paths欄位呢?
方法1:使用函式
update cfg_team set paths = fn_team_paths(team_id)
where team_id = 3 and parent_id = 1
方法2:使用觸發器,呵呵,首先這個表是基礎性的表,不需要頻繁更新,所以觸發器的效能、效率等都不是問題,問題關鍵是自動更新,insert資料時根據parent_id計算當前的paths、update資料時計算當前paths和parent_id為當前team_id的記錄,這便是遞迴更新,實驗了很久下面直接給出**,能不能領悟看運氣吧
--開啟觸發器遞迴
alter database [database]
set recursive_triggers on
goif exists (select name from sysobjects where name = 'team_insert' and type = 'tr')
drop trigger team_insert
go--建立insert觸發器
create trigger team_insert
on cfg_team
after insert
as --插入新記錄時自動更新該記錄的paths值
update t set paths = case
when isnull(p.paths, '') = '' then ltrim(str(p.team_id)) + '.' + ltrim(str(t.team_id))
else p.paths + '.' + ltrim(str(t.team_id))
end
from cfg_team t, inserted i, cfg_team p
where t.team_id = i.team_id and i.parent_id = p.team_id and i.parent_id <> 0 go
if exists (select name from sysobjects where name = 'team_update' and type = 'tr')
drop trigger team_update
go--建立update觸發器
create trigger team_update
on cfg_team
after update
as --1、若有記錄parent_id值變更
if update(parent_id) and exists(select * from inserted)
begin
--2、更新變更記錄的paths值(parent_id == 0)
update t set paths = ''
from cfg_team t, inserted i
where t.team_id = i.team_id and t.parent_id = 0
--3、更新變更記錄的paths值(parent_id <> 0)
update t set paths = case
when isnull(p.paths, '') = '' then ltrim(str(p.team_id)) + '.' + ltrim(str(t.team_id))
else p.paths + '.' + ltrim(str(t.team_id))
end
from cfg_team t, inserted i, cfg_team p
where t.team_id = i.team_id and i.parent_id = p.team_id and i.parent_id <> 0
--4、重新整理變更下級記錄parent_id,讓系統自動遞迴更新
update t set t.parent_id = t.parent_id
from cfg_team t, inserted i
where t.parent_id = i.team_id
end
sql 觸發器 直接遞迴觸發器
create trigger dbo loving20000 on dbo s for delete asdeclare age int select age sage from deleted delete s where sage age delete from s where sname xq...
sqlserver觸發器複習
create table a a1 int,a2 int create table b b1 int,b2 int insert into a values 1,0 insert into b values 1,0 create trigger tri update a2 a on a for up...
SQL server 之 觸發器
今天對觸發器研究了一下,之前的學習感覺挺朦朧的,今天鼓搗了一天,算是有了一點點了解,把學習的體會記錄了下來。常見的觸發器 觸發器的作用 自動化操作,減少了手動操作以及出錯的機率 現實工作中用的比較少,因為想讓他執行起來效率高很難 一 dml觸發器 insert delete update 不支援se...