更新多個連接表的視圖
由於 MSDN 並沒有說太多,如果我執行以下查詢會發生什麼?
update claims set status='Awaiting Auth.' where status = 'Approved'
我可以使用
ClaimStatusName
連結表的列dimClaimStatus
來更新通過外鍵引用的主表嗎?視圖本身查詢多個表,主表是
tabData
,我也想用上面的查詢更新。我想從 FK 這意味著fiClaimStatus
在引用表中更改為. 它是這樣工作的嗎?tabData
Approved``dimClaimStatus``Awaiting Auth.
tabData 中的每一行只能有一個視圖行。
這是視圖:
CREATE VIEW [dbo].[Claims] AS SELECT mu.MarketUnitName AS MarketUnit, c.CountryName AS Country, gsp.GSPName AS GSP, gsp.WCMSKeyNumber AS GspNumber, sl.SLName AS SL, sl.WCMSKeyNumber AS SlNumber, m.ModelName AS Model, m.SalesName AS [Model-Salesname], s.ClaimStatusName AS [Status], d.Work_Order AS [Work Order], d.SSN_Number AS IMEI, .... more columns .... idData, -- PK of main table tabData fiSL, fiModel, fiClaimStatus -- FK to dimClaimStatus FROM tabData AS d INNER JOIN locSL AS sl ON d.fiSL = sl.idSL INNER JOIN locGSP AS gsp ON sl.fiGSP = gsp.idGSP INNER JOIN locCountry AS c ON gsp.fiCountry = c.idCountry INNER JOIN locMarketUnit AS mu ON c.fiMarketUnit = mu.idMarketUnit INNER JOIN modModel AS m ON d.fiModel = m.idModel INNER JOIN dimClaimStatus AS s ON d.fiClaimStatus = s.idClaimStatus INNER JOIN tdefProductType ON d.fiProductType = tdefProductType.idProductType LEFT OUTER JOIN tdefServiceLevel ON d.fimaxServiceLevel = tdefServiceLevel.idServiceLevel LEFT OUTER JOIN tdefActionCode AS ac ON d.fimaxActionCode = ac.idActionCode
更新
由於該表包含 2000 萬條客戶記錄,因此我想先知道在執行它之前會發生什麼。在評論和回答之後,我現在已經執行了。直接結果是:
(1 row(s) affected)
令人驚訝的是,有數千條處於此狀態的記錄現在似乎已更新。
更新 2
實際上它並沒有按預期工作,懷疑
(1 row(s) affected)
是正確的。僅更新了引用的表。所以現在狀態Approved
變成了Awaiting Auth.
。結論:
這似乎是避免使用視圖進行更新的最佳方式。這適用於我的情況:
UPDATE tabData SET fiClaimStatus = (SELECT idClaimStatus FROM dimClaimStatus WHERE ClaimStatusName = 'Awaiting auth.') WHERE fiClaimStatus=(SELECT idClaimStatus FROM dimClaimStatus WHERE ClaimStatusName = 'Approved')
一般視圖可更新性
CREATE VIEW (Transact-SQL)
文件的關鍵部分是:通常,數據庫引擎必須能夠明確地跟踪從視圖定義到一個基表的修改。
請注意,即使視圖在技術上是可更新的,但由於查詢處理器推理的限制,它實際上可能無法在實踐中更新。這就是“……數據庫引擎必須能夠……”這句話背後的微妙之處。
確保視圖實際上可更新的最簡單方法是請求更新查詢的預執行(“估計”)計劃。如果出現錯誤,要麼視圖在邏輯上不可更新,要麼查詢處理器無法判斷它是。
自然,請求“估計”計劃不涉及執行查詢。顯示的計劃還將顯示查詢優化器能夠刪除多少視圖定義(因為它是多餘的)。通常,它在這方面做得很好,因此更新視圖計劃可能看起來非常類似於對單個受影響的基表進行簡單更新的計劃。
具體例子
我可以使用連結表dimClaimStatus的**ClaimStatusName列來更新通過外鍵引用的主表嗎?
$$ … $$我想更改tabData中的 fiClaimStatus。
不使用您發布的查詢:
update claims set status='Awaiting Auth.' where status = 'Approved'
這會更改與視圖的公開列名稱status關聯的基表列。從視圖定義來看,這是表 dimClaimStatus 中列 ClaimStatusName的**別名。
執行計劃顯示,dimClaimStatus是通過視圖更新的表:
如果你想更新
fiClaimStatus
,那就是你需要在更新語句中指定的列。如果這涉及查找,您可能無法直接使用視圖,正如您最初想要的那樣,但您可以編寫如下內容:update claims set fiClaimStatus = ( select CS.idClaimStatus from dbo.dimClaimStatus AS CS where CS.ClaimStatusName = 'Awaiting auth.' ) where status = 'Approved';`