中文字幕天天躁日日躁狠狠躁,最近中文字幕大全免费版在线,最近2019免费中文字幕视频三,亚洲精品无码你懂的,亚洲国产精品成人精品小说

  • 相關(guān)軟件
    >SQL Server(存儲(chǔ)過(guò)程)臨時(shí)表與滯后名稱解析 創(chuàng)建者:webmaster 更新時(shí)間:2022-01-13 10:18

    開發(fā)中,我們經(jīng)常用Create Procedure命令創(chuàng)建存儲(chǔ)過(guò)程,而在創(chuàng)建過(guò)程時(shí)實(shí)際發(fā)生的是,Query Analyzer檢查其語(yǔ)法,檢查完畢并正確后將其插入系統(tǒng)表syscomments中,而在過(guò)程中引用的對(duì)象名稱在該過(guò)程被執(zhí)行之前不被解析,這個(gè)技術(shù)叫做滯后名稱解析。然而,這個(gè)技術(shù)卻并不是和我們想象的一樣,它也有鞭長(zhǎng)莫及的地方。下面來(lái)看一個(gè)過(guò)程:



    CREATE PROC testp @var int



    AS



    IF @var=1



      CREATE TABLE #mytemp(k1 int identity,c1 int)



    ELSE



      CREATE TABLE #mytemp(k1 int identity,c1 varchar(2))



    INSERT #mytemp DEFAULT VALUES



    SELECT c1 FROM #mytemp



    GO



    當(dāng)編譯該過(guò)程時(shí),出現(xiàn)以下錯(cuò)誤:








    也許你會(huì)問(wèn),@var不可能既等于1又不等于1,那問(wèn)什麼會(huì)出現(xiàn)以上的錯(cuò)誤呢?大家不要頭暈,現(xiàn)在是在檢查語(yǔ)法的時(shí)候,檢查語(yǔ)法是逐行向下的,編譯器不會(huì)管你的@var等不等于1,它只檢查語(yǔ)法錯(cuò)誤!可能你又要說(shuō):上面不是說(shuō)對(duì)象名稱滯后解析嗎?臨時(shí)表就是一個(gè)對(duì)象啊,而#mytemp是它的名稱,既然是滯后解析,那就是忽略該名稱不解析,怎麼可能會(huì)出現(xiàn)這種錯(cuò)誤,別急,問(wèn)題就出在這里!對(duì)比看一下下面的過(guò)程:



    CREATE PROC testp2 @var int



    AS



    IF @var=1



      CREATE TABLE tempdb..mytemp(k1 int identity,c1 int)



    ELSE



      CREATE TABLE tempdb..mytemp(k1 int identity,c1 varchar(2))



    INSERT mytemp DEFAULT VALUES



    SELECT c1 FROM mytemp



    GO



    奇怪的事情發(fā)生了,創(chuàng)建這個(gè)過(guò)程順利地通過(guò),這里只是把臨時(shí)表替換成了一個(gè)永久性表,并沒(méi)做其他任何改變,難道SQL Server在乎創(chuàng)建的是臨時(shí)表還是永久性表,呵呵?發(fā)生的事情似乎是這樣的,在將過(guò)程插入syscomments之前(存儲(chǔ)過(guò)程編譯后存放于系統(tǒng)表syscomments中), SQL Server參照臨時(shí)表解析CREATE TABLE,也許你會(huì)說(shuō)將臨時(shí)表?yè)Q成一個(gè)table類型的變量就不會(huì)出現(xiàn)這樣的問(wèn)題,可是事實(shí)是不行,數(shù)據(jù)類型table同樣受此局限。似乎是從SQL Server 7.0開始,支持永久性表的滯后名稱解析,但不支持臨時(shí)表的滯后名稱解析。但不管是哪一種情況,第一個(gè)代碼都無(wú)法執(zhí)行,下面采取一個(gè)迂回策略來(lái)解決這個(gè)問(wèn)題,請(qǐng)看:



    CREATE PROC testp @var int



    AS



    CREATE TABLE #mytemp(k1 int identity)



    IF @var=1



      ALTER TABLE #mytemp ADD c1 int



    ELSE



      ALTER TABLE #mytemp ADD c1 varchar(2)



    INSERT #mytemp DEFAULT VALUES



    EXEC('SELECT c1 FROM #mytemp')



    GO



    在這里只創(chuàng)建表一次,然后修改它,注意`EXEC('SELECT c1 FROM #mytemp')'



    這條語(yǔ)句是必要的,因??新添加的列對(duì)于添加它的過(guò)程并非立即可見,如果去掉EXEC執(zhí)行該過(guò)程時(shí),將會(huì)顯示這樣的錯(cuò)誤:








    再説一次,新添加的列對(duì)于添加它的過(guò)程并非立即可見!然而以上的代碼卻帶來(lái)了一個(gè)性能問(wèn)題,因??任何創(chuàng)建臨時(shí)表并近一步處理它的存儲(chǔ)過(guò)程都將導(dǎo)致該過(guò)程的執(zhí)行計(jì)劃重新編譯,這對(duì)于高吞吐量環(huán)境中的大型過(guò)程而言,性能會(huì)大打折扣!以下過(guò)程將解決這個(gè)問(wèn)題:



    CREATE PROC test4



    AS



    INSERT #temp DEFAULT VALUES



    SELECT c1 FROM #temp



    GO







    CREATE PROC test3



    AS



    CREATE TABLE #temp (k1 int identity,c1 varchar(2))



    EXEC dbo.test4



    GO







    CREATE PROC test2



    AS



    CREATE TABLE #temp (k1 int identity,c1 int)



    EXEC dbo.test4



    GO







    CREATE PROC test @var int



    AS



    IF @var=1



      EXEC dbo.test2



    ELSE



      EXEC dbo.test3



    GO



    復(fù)雜性提高了,但是還是可以解決一些問(wèn)題,另外,之所以在第二和第三個(gè)過(guò)程中冗余地調(diào)用第四個(gè)過(guò)程,是因??臨時(shí)表一旦超過(guò)其作用域就自動(dòng)被刪除!
    相關(guān)文章
    本頁(yè)查看次數(shù):