EXEC(EXECUTE)函數(shù)訪(fǎng)問(wèn)INSERTED或DELETED的內(nèi)部臨時(shí)觸發(fā)表
更新時(shí)間:2012年01月20日 21:32:08 作者:
近段時(shí)間,MS SQL方面,一直需要開(kāi)發(fā)動(dòng)態(tài)方面的存儲(chǔ)過(guò)程或是觸發(fā)器以及表函數(shù)。因?yàn)槌绦蛟O(shè)計(jì)一開(kāi)始就是讓用戶(hù)動(dòng)態(tài)添或是刪除一個(gè)表的字段,然而這個(gè)表的相關(guān)存儲(chǔ)過(guò)程或是觸發(fā)器以及為報(bào)表準(zhǔn)備的表函數(shù)也會(huì)隨之這個(gè)表的字段變化而變化
剛開(kāi)始時(shí),這個(gè)表的字段很少(10個(gè)以?xún)?nèi)),前開(kāi)發(fā)者把這個(gè)表的所有存儲(chǔ)過(guò)程與觸發(fā)器以及表函數(shù)全是寫(xiě)死了。用戶(hù)每添加一些字段,都需要手動(dòng)去更改這些存儲(chǔ)過(guò)程與觸發(fā)器以及表函數(shù)?,F(xiàn)在這個(gè)表的字段已經(jīng)高達(dá)300個(gè)以上,有可能還會(huì)增長(zhǎng),因此Insus.NET的業(yè)務(wù)就是把這此靜態(tài)全改寫(xiě)為動(dòng)態(tài)處理。
然而有一個(gè)問(wèn)題一直困攏至昨天,昨天是星期天本應(yīng)是休息的,但是這個(gè)問(wèn)題沒(méi)有解決,因此這天算不上休息了。
問(wèn)題就是改寫(xiě)表的觸發(fā)器,涉及到EXEC(EXECUTE)函數(shù)訪(fǎng)問(wèn)INSERTED或DELETED的內(nèi)部臨時(shí)觸發(fā)表,如:
EXECUTE('SELECT '+ @N +' = ISNULL(['+ @I +'],0) FROM inserted')
當(dāng)你嘗試執(zhí)行上面的SQL語(yǔ)句,會(huì)得到一個(gè)異常提示:invalid object name 'inserted'。我們無(wú)法顯示訪(fǎng)問(wèn)INSERTED或DELETED的內(nèi)部臨時(shí)觸發(fā)表。
由于INSERTED或是DELETED表是動(dòng)態(tài)駐留在內(nèi)存中,而不是存儲(chǔ)在數(shù)據(jù)庫(kù)中,它不是顯式的。觸發(fā)器的執(zhí)行是在導(dǎo)致觸發(fā)器被觸發(fā)的執(zhí)行計(jì)劃中。當(dāng)我們使用EXEC(EXECUTE)或sp_executesql執(zhí)行動(dòng)態(tài)生成的SQL語(yǔ)句時(shí),它卻是另外一個(gè)單獨(dú)的執(zhí)行計(jì)劃。兩者之間的資源無(wú)法相互訪(fǎng)問(wèn),再加上計(jì)劃執(zhí)行完畢,內(nèi)存也隨之釋放資源了。
但是問(wèn)題還是需要解決,Insus.NET想起的還是臨時(shí)表??梢园袸NSERTED或DELETED表中的數(shù)據(jù),首先轉(zhuǎn)換入臨時(shí)表了。這樣子,我們就可以對(duì)臨時(shí)表的數(shù)據(jù)進(jìn)行處理了。
SELECT * INTO #inserted FROM INSERTED
SELeCT * INTO #deleted FROM DELETED
實(shí)現(xiàn)代碼:
DECLARE @F NVARCHAR(MAX) = CONVERT(NVARCHAR(MAX),@I) --@I動(dòng)態(tài)字段
EXECUTE ('SELECT ['+ @F +'] FROM #deleted)
然而有一個(gè)問(wèn)題一直困攏至昨天,昨天是星期天本應(yīng)是休息的,但是這個(gè)問(wèn)題沒(méi)有解決,因此這天算不上休息了。
問(wèn)題就是改寫(xiě)表的觸發(fā)器,涉及到EXEC(EXECUTE)函數(shù)訪(fǎng)問(wèn)INSERTED或DELETED的內(nèi)部臨時(shí)觸發(fā)表,如:
復(fù)制代碼 代碼如下:
EXECUTE('SELECT '+ @N +' = ISNULL(['+ @I +'],0) FROM inserted')
當(dāng)你嘗試執(zhí)行上面的SQL語(yǔ)句,會(huì)得到一個(gè)異常提示:invalid object name 'inserted'。我們無(wú)法顯示訪(fǎng)問(wèn)INSERTED或DELETED的內(nèi)部臨時(shí)觸發(fā)表。
由于INSERTED或是DELETED表是動(dòng)態(tài)駐留在內(nèi)存中,而不是存儲(chǔ)在數(shù)據(jù)庫(kù)中,它不是顯式的。觸發(fā)器的執(zhí)行是在導(dǎo)致觸發(fā)器被觸發(fā)的執(zhí)行計(jì)劃中。當(dāng)我們使用EXEC(EXECUTE)或sp_executesql執(zhí)行動(dòng)態(tài)生成的SQL語(yǔ)句時(shí),它卻是另外一個(gè)單獨(dú)的執(zhí)行計(jì)劃。兩者之間的資源無(wú)法相互訪(fǎng)問(wèn),再加上計(jì)劃執(zhí)行完畢,內(nèi)存也隨之釋放資源了。
但是問(wèn)題還是需要解決,Insus.NET想起的還是臨時(shí)表??梢园袸NSERTED或DELETED表中的數(shù)據(jù),首先轉(zhuǎn)換入臨時(shí)表了。這樣子,我們就可以對(duì)臨時(shí)表的數(shù)據(jù)進(jìn)行處理了。
復(fù)制代碼 代碼如下:
SELECT * INTO #inserted FROM INSERTED
SELeCT * INTO #deleted FROM DELETED
實(shí)現(xiàn)代碼:
復(fù)制代碼 代碼如下:
DECLARE @F NVARCHAR(MAX) = CONVERT(NVARCHAR(MAX),@I) --@I動(dòng)態(tài)字段
EXECUTE ('SELECT ['+ @F +'] FROM #deleted)
相關(guān)文章
SQLServer中master數(shù)據(jù)庫(kù)分析
sql下master數(shù)據(jù)庫(kù)分析,了解下master數(shù)據(jù)庫(kù)主要是做什么用的2008-04-04SQLServer行列互轉(zhuǎn)實(shí)現(xiàn)思路(聚合函數(shù))
這篇文章主要為大家詳細(xì)介紹了SQLServer行列互轉(zhuǎn)實(shí)現(xiàn)思路,使用聚合函數(shù)pivot/unpivot實(shí)現(xiàn)行列互轉(zhuǎn),感興趣的小伙伴們可以參考一下2016-03-03sql2000報(bào)錯(cuò)Successfully re-opened the local eventlog解決方法
這篇文章主要介紹了sql2000報(bào)錯(cuò)Successfully re-opened the local eventlog解決方法,需要的朋友可以參考下2014-12-12SQL Server中Check約束的學(xué)習(xí)教程
這篇文章主要介紹了SQL Server中Check約束的學(xué)習(xí)教程,包括對(duì)啟用Check約束來(lái)提升性能的介紹,需要的朋友可以參考下2015-12-12sql server中錯(cuò)誤日志errorlog的深入講解
很多時(shí)候診斷SQLSERVER問(wèn)題都需要看SQLSERVER的錯(cuò)誤日志,所以下面這篇文章主要給大家介紹了關(guān)于sql server中錯(cuò)誤日志errorlog的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-10-10解決sql server 數(shù)據(jù)庫(kù),sa用戶(hù)被鎖定的問(wèn)題
這篇文章主要介紹了解決sql server 數(shù)據(jù)庫(kù),sa用戶(hù)被鎖定的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06SQLServer中匯總功能的使用GROUPING,ROLLUP和CUBE
查看SQL Server的幫助才發(fā)現(xiàn),厲害啊,原來(lái)還有這么厲害的東西,不由的想起以前做水晶報(bào)表的時(shí)候,原來(lái)在SQL Server中就可以實(shí)現(xiàn)這樣的功能.2010-07-07