SQLServer觸發器遞迴更新

2021-06-12 07:38:47 字數 3028 閱讀 2184

起因:有乙個組表,是樹型結構,結構如下:

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...