我們在應用程序開發(fā)的時候,經(jīng)常會遇到這樣的一種情況:附屬表更新了,主表的數(shù)據(jù)沒有更新,這個關聯(lián)表不只是外鍵的關聯(lián)(通過附屬表 ID 關聯(lián)),主表中還會存在一些附屬表的字段,這樣一般做的目的是,在查詢顯示的時候減少關聯(lián)(性能考慮)。凡事都有相對性,比如我們有時候會對附屬表中的數(shù)據(jù)進行更新,如果沒有對附屬字段添加觸發(fā)器,這時候就造成附屬表中的數(shù)據(jù)和主表不一致,沒辦法,我們需要對這些“過時數(shù)據(jù)”進行手動“刷新”。
比如我們有 PRoduct 和 Provider 表,一個商品對應一個提供商,表結(jié)構(gòu)如下(只做演示):
Product 和 Provider 表之間的關系通過 ProviderID 字段進行關聯(lián),ProviderName 這個字段就是上面我們說,為了減少關聯(lián)查詢用的,那如果 Provider 表中的 Name 值更新了,如何更新 Product 表中的 ProviderName 值呢?
問題分析這個數(shù)據(jù)更新的問題,其實現(xiàn)在看來非常簡單,但是我當時在解決這個問題的時候,莫名其妙多了很多想法,對于程序員來說,兩個數(shù)據(jù)集的對應數(shù)據(jù)更新,我們怎么處理呢?最簡單的是遍歷然后再另一個數(shù)據(jù)集中進行查找,然后對查找后的結(jié)果進行修改保存,這是一般做法,比如下面的這段偽代碼:
DataView product = new DataView(); DataView provider = new DataView(); foreach (DataRow item in provider) { product.RowFilter = string.Format("ProviderID={0}", item["ID"]); //todo... }
上面這段代碼是我們一般不經(jīng)過大腦寫出來的,試著想一下,如果存在幾十萬甚至幾百萬的數(shù)據(jù),這種方式程序肯定會運行到明年,不可否認,當時我想過這種方式實現(xiàn)的,而且還是想寫個程序腳本來完成數(shù)據(jù)更新,這是多么的不靠譜啊。
如果不用程序去完成數(shù)據(jù)更新,我們就得寫 SQL 腳本,數(shù)據(jù)庫也不是很熟悉,只能說會簡單的語法(select),連修改列的屬性都忘了,幸虧在去年畢業(yè)的時候,整理了一個簡單 T-SQL 系列《T-Sql學習系列完結(jié)》,現(xiàn)在看來,當時真是太明智了,雖然這些簡單的語法網(wǎng)上一找一大堆,但還是覺得自己整理的看著舒服。
實現(xiàn)上面數(shù)據(jù)更新有很多方式,我當時還想過用游標操作,但是一想和程序中的 foreach 有什么區(qū)別的呢?還是覺得干點實事吧,最后有了下面的一段 SQL 腳本,針對上面 Product 和 Provider 表的數(shù)據(jù)更新:
update [dbo].[Product] set [dbo].[Product].ProviderName=[dbo].[Provider].Name from [dbo].[Provider] where [dbo].[Product].ProviderID=[dbo].[Provider].ID and ....
就這么簡單,當時卻花了很長的時間,甚至還有個疑問:不是一個數(shù)據(jù)庫的表進行數(shù)據(jù)更新,可以用 SQL 實現(xiàn)嗎?有點可笑,其實一個數(shù)據(jù)庫實例下,跨數(shù)據(jù)庫訪問表的話,直接在表名之前加數(shù)據(jù)庫名稱就行了。
新聞熱點
疑難解答
圖片精選