環球網校是美國納斯達克上市企業歡聚時代(NASDAQ:YY)旗下品牌 | 住房和城鄉建設部 建筑人才培訓合作單位
您現在的位置在: > 計算機類 > 計算機等級考試 > 考試輔導 >

SqlServer2000的視圖中 小心使用*號

2010-06-27 來源:互聯網 作者:第一考試網

SqlServer2000的視圖中 小心使用*號 #

  有些朋友看到這個標題可能會有疑問,難道在視圖中使用*符號還有何要注意的地方嗎?對于這個問題,我們先不必回答,先看一下例子吧。
  我這里,使用的數據庫是SqlServer2000自帶的Northwind,這樣方便大家自己私下里測試。首先,創建兩個視圖,視圖的腳本如下:
  --視圖 vCustomersA
  create view vCustomersA
  as
  select CustomerID ,CompanyName,ContactName,ContactTitle,
  Address,City,Region,PostalCode,Country,Phone,Fax
  from dbo.Customers
  go
  --視圖 vCustomersB
  create view vCustomersB
  as
  select * from vCustomersA
  go
  然后,使用這兩個視圖查詢客戶ID為ALFKI的資料,查詢語句如下:
  select * from vCustomersA where CustomerID = 'ALFKI'
  select * from vCustomersB where CustomerID = 'ALFKI'
  查詢的結果如下:
  一切正常,這個時候,需求發生了變化,我們需要改動vCustomersA,改動后的腳本如下:(為了說明問題,我們只是把CompanyName和ContactName互換一下位置) #
  --改動后的視圖vCustomersA
  alter view vCustomersA
  as
  select CustomerID ,ContactName,CompanyName,ContactTitle,
  Address,City,Region,PostalCode,Country,Phone,Fax
  from dbo.Customers
  go
  這個時候,當我們再次使用視圖vCustomersB查詢客戶ID為ALFKI的資料的時候,錯誤已經悄然來臨,你注意到了嗎?讓我們來看一下這兩個視圖的查詢結果吧,查詢語句如下:
  select * from vCustomersA where CustomerID = 'ALFKI'
  select * from vCustomersB where CustomerID = 'ALFKI'
  查詢的結果發生變化。你注意到數據的異常了嗎?使用視圖vCustomersB查詢的結果出現了錯誤,CompanyName顯示的資料是:Maria Anders,而在視圖vCustomersA查詢的結果中CompanyName是:Alfreds Futterkiste。我們僅僅是在vCustomersA中互換了兩個字段的位置,再次使用vCustomersB查詢數據卻發生了數據錯位的現象,這是什么原因導致的呢?
  帶著這個問題,讓我們去了解一下,何謂視圖?在Sql Server2000的幫助文檔中是這樣描述視圖的,定義如下:“視圖是一個虛擬表,其內容由查詢定義,同真實的表一樣,視圖包含一系列帶有名稱的列和行數據。但是,視圖并不在數據庫中以存儲的數據值集形式存在。行和列數據來自由定義視圖的查詢所引用的表,并且在引用視圖時動態生成。”通過這個定義我們可以看出,視圖是一個虛擬的表,它僅僅包括視圖的定義腳本,查詢的內容則是動態的生成。當我們創建了一個視圖以后,視圖的腳本會保存到當前數據庫的系統表syscomments里,我們可以通過系統提供的存儲過程:sp_helptext查詢得到視圖的定義腳本。從定義上看,好像并不能得到我們想要的答案,那么我們就先不管Sql Server2000是如何實現視圖的,我們先來解決一下當前的問題(我上面提到的)。可能有些朋友已經知道了解決問題的辦法了,那就是把vCustomersB的定義腳本重新執行一下(其實只需要把create換成alter執行一下就可以),腳本如下:

#


  --重新執行一下vCustomersB的定義腳本
  alter view vCustomersB
  as
  select * from vCustomersA
  go
  那么,除了這個方法以外,其實SqlServer2000也提供了一個擴展存儲過程sp_refreshview來幫我們做這件事情,調用的腳本如下:
  --刷新指定視圖的元數據
  exec sp_refreshview 'vCustomersB'
  我個人目前就知道這兩個辦法,不知道,你還有沒有其他的辦法,有的話可以一起分享一下。
  sp_refreshview的功能描述為:“刷新指定視圖的元數據。由于視圖所依賴的基礎對象的更改,視圖的持久元數據會過期。”由于sp_refreshview的代碼被封裝了(沒有公開),所以我們看不到它的內部實現,不過看了這個存儲過程的描述,你是否對視圖有了新的認識呢?#p#分頁標題#e#
  從這里,我們可以看到,當我們使用一個視圖查詢數據的時候,其實我們是在使用視圖的元數據來查詢的,當視圖依賴的對象發生了變化以后,視圖的元數據就需要更新,這樣,使用視圖時才不會違背我們的意愿。
  知道了問題的產生的原因后,那么我們在重新修改一個表或視圖的腳本時,我們就需要更新依賴于該對象的視圖,否則就會出現意想不到的錯誤。如何找到依賴于該對象的對象(包括視圖,觸發器,存儲過程)呢?SqlServer2000在該數據庫的系統表sysdepends里記錄這些依賴關系,所以你可以查詢該表獲取你想要的信息,但其實,你可以通過使用系統提供的存儲過程:sp_depends來獲取該對象的所依賴的對象(返回的第一個表)以及依賴于該對象的對象(返回的第二個表),腳本如下:
#

  --查詢vCustomersA的依賴的對象以及依賴于vCustomersA的對象
  exec sp_depends 'vCustomersA'
  查詢的結果如下圖:
  注:sp_depends的代碼是公開的,有興趣的可以看一下其實現過程。
  到此,你應該明白,當你更新你的表或視圖的時候,你還要刷新依賴于這些對象的視圖的元數據,即需要調用sp_refreshview來刷新依賴于該對象的視圖。但是你在查詢依賴于一個表或者視圖的對象集合的時候需要注意的一點是,在你更新了一個表或視圖之后,那些之前創建的依賴于該表或視圖的依賴關系將會丟失(你更新的表或視圖所依賴的對象集合不會丟失),用我之前的例子來看,vCustomersB依賴于vCustomersA,那么當我們修改了vCustomersA以后,vCustomersB與vCustomersA之間的依賴關系將會丟失而vCustomersA所依賴的Customers將不會丟失(依賴關系在對象創建或更新時創建,更新時,會把先前的依賴關系刪掉)。(調用sp_depends你就可以看出來這種微妙的變化)
  第一考試網希望在你閱讀了本文以后,你在使用視圖的時候會更加的得心應手,避免錯誤發生。 #

責編:admin 返回頂部  打印

彩票33 宜都 | 日土 | 萍乡 | 丹阳 | 荆门 | 辽源 | 巴彦淖尔市 | 酒泉 | 万宁 | 白沙 | 伊春 | 宁国 | 清徐 | 北海 | 湖北武汉 | 佛山 | 温州 | 武威 | 馆陶 | 嘉兴 | 河源 | 红河 | 海安 | 韶关 | 桓台 | 张北 | 枣庄 | 寿光 | 平凉 | 绵阳 | 绥化 | 吉林长春 | 咸阳 | 湛江 | 简阳 | 河源 | 克拉玛依 | 牡丹江 | 东海 | 阳春 | 吐鲁番 | 黄冈 | 湘西 | 招远 | 黄冈 | 乐山 | 内江 | 吕梁 | 张掖 | 改则 | 汕尾 | 长垣 | 河池 | 四平 | 雅安 | 任丘 | 荆门 | 永州 | 平顶山 | 广汉 | 鄂州 | 驻马店 | 喀什 | 商洛 | 安吉 | 海南海口 | 公主岭 | 嘉兴 | 正定 | 抚州 | 松原 | 莆田 | 桓台 | 澄迈 | 济源 | 澳门澳门 | 湘潭 | 巴彦淖尔市 | 乐山 | 常州 | 诸暨 | 垦利 | 桐乡 | 金华 | 巴彦淖尔市 | 澳门澳门 | 佛山 | 烟台 | 浙江杭州 | 澄迈 | 邹城 | 巴中 | 淮南 | 灌南 | 平潭 | 永州 | 盐城 | 秦皇岛 | 三亚 | 澄迈 | 牡丹江 | 招远 | 吉林 | 云南昆明 | 海北 | 吉林长春 | 滨州 | 湖州 | 台湾台湾 | 昭通 | 梧州 | 广汉 | 盐城 |