假設(shè)有這樣的組織層次,“某某局”,“某某局>某某部”,“某某局>某某部>某某下屬組織”,
“某某局”是一級(jí)組織所以他的組織層次就是他自己的組織名字,而類(lèi)似“某某部”這樣的二級(jí)組織,他們的組織層次就是“某某局>某某部”,中間用“>”(大于號(hào))分隔,從一級(jí)組織一直到他自己的組織名字連接起來(lái)。
這個(gè)組織層次的屬性一般只用于展示,而且經(jīng)常會(huì)在列表中和其他屬性展示出來(lái),所以我們?cè)跀?shù)據(jù)表的某個(gè)字段中將其保存下來(lái),不會(huì)每次都去查詢(xún)?nèi)缓筮B接起來(lái);只在組織層次變更的時(shí)候更新受影響的記錄。
比如,當(dāng)“某某部”的組織層次發(fā)生了變化,由原來(lái)的“某某局”的下級(jí)組織變成了“某某新劇”的下級(jí)組織,此時(shí),“某某部”的組織層次需要修改為“某某新局>某某部”(這一步是已知條件,我們可以很容易就做到),因而他的下級(jí)組織(包括下級(jí)的下級(jí))都需要更新組織層次(級(jí)聯(lián)更新的),組織層次的變動(dòng)也可能是跨層次的。
一種比較好的做法就是將“某某部”原來(lái)的組織層次備份起來(lái),獲取到新的組織層次,然后用原來(lái)的組織層次到數(shù)據(jù)庫(kù)中做like,將like的結(jié)果做replace,
update organization set pathname=REPLACE(pathname, "某某局>某某部", "某某新局>某某部"); www.itzg.net
而且like的結(jié)果就是所有需要變更的記錄,不需要去遞歸查詢(xún)(遞歸查詢(xún)是個(gè)災(zāi)難)。
由于一開(kāi)始沒(méi)有想到這樣的方法,我走了彎路,而且還遇到了問(wèn)題,下面就開(kāi)始記一記。
已知被修改的組織“某某部”,和現(xiàn)在他的新組織層次“某某新局>某某部”,要求去修改他的下級(jí)組織的組織層次(級(jí)聯(lián))。
所以我是這樣子的:
SELECT CONCAT("某某新局>某某部",">",RIGHT("某某局>某某部>某某下屬組織", LENGTH("某某局>某某部>某某下屬組織") - (LOCATE("某某部","某某局>某某部>某某下屬組織") + LENGTH("某某部"))));
這個(gè)句子很長(zhǎng),最外層是CONCAT,目的是將"某某新局>某某部"與">某某下屬組織"拼接起來(lái);再看RIGHT部分。這部分為了獲得“某某局>某某部>某某下屬組織”的"某某下屬組織",需要計(jì)算出來(lái)"某某下屬組織"的長(zhǎng)度。首先定位LOCATE到“某某部”的起點(diǎn),再加上“某某部”的長(zhǎng)度,自然這個(gè)offset后面就是"某某下屬組織"的內(nèi)容,所以用整體長(zhǎng)度LENGTH("某某新局>某某部"與">某某下屬組織")減去上面計(jì)算所得的offset。
只不過(guò)這個(gè)SQL得到的結(jié)果是錯(cuò)誤的。
如果是這樣才是正確的:www.itzg.net
SELECT CONCAT("某某新局>某某部",">",RIGHT("某某局>某某部>某某下屬組織", CHAR_LENGTH("某某局>某某部>某某下屬組織") - (LOCATE("某某部","某某局>某某部>某某下屬組織") + CHAR_LENGTH("某某部"))));
mysql> SELECT * FROM test.organization; +----+--------------+----------------------------+ | id | name | pathname | +----+--------------+----------------------------+ | 1 | 某某局 | 某某局 | | 2 | 某某部 | 某某局>某某部 | | 3 | 某某下屬組織 | 某某局>某某部>某某下屬組織 | | 4 | 某某新局 | 某某新局 | +----+--------------+----------------------------+ 4 rows in set mysql> UPDATE test.organization SET PATHNAME = '某某新局>某某部' WHERE ID = 2; Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT * FROM test.organization; +----+--------------+----------------------------+ | id | name | pathname | +----+--------------+----------------------------+ | 1 | 某某局 | 某某局 | | 2 | 某某部 | 某某新局>某某部 | | 3 | 某某下屬組織 | 某某局>某某部>某某下屬組織 | | 4 | 某某新局 | 某某新局 | +----+--------------+----------------------------+ 4 rows in set mysql> UPDATE test.organization SET PATHNAME=CONCAT('某某新局>某某部', '>', RIGHT('某某局>某某部>某某下屬組織', CHAR_LENGTH('某某局>某某部>某某下屬組織') - ( LOCATE('某某部', '某某局>某某部>某某下屬組織') + CHAR_LENGTH('某某部') ) ) ) WHERE ID=3; Query OK, 1 row affected Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT * FROM test.organization; +----+--------------+------------------------------+ | id | name | pathname | +----+--------------+------------------------------+ | 1 | 某某局 | 某某局 | | 2 | 某某部 | 某某新局>某某部 | | 3 | 某某下屬組織 | 某某新局>某某部>某某下屬組織 | | 4 | 某某新局 | 某某新局 | +----+--------------+------------------------------+ 4 rows in set
更多信息請(qǐng)查看IT技術(shù)專(zhuān)欄