MSDNは多くのことを述べていないので、次のクエリを実行するとどうなりますか?
update claims set status='Awaiting Auth.'
where status = 'Approved'
リンクテーブルClaimStatusName
のdimClaimStatus
列を使用して、外部キーを介して参照されるメインテーブルを更新できますか?
ビュー自体が複数のテーブルをクエリします。メインテーブルはtabData
です。これも上記のクエリで更新します。 fiClaimStatus
のtabData
を、参照されているテーブルApproved
の__meansdimClaimStatus
からAwaiting Auth.
へのFKから変更します。このように機能しますか?
TabDataの行ごとに1つのビュー行のみが可能です。
これがビューです:
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)
これは驚くべきことです。このステータスには数千のレコードがあり、現在更新されているようです。
実際には期待どおりに動作せず、疑わしい(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)
documentation の重要な部分は次のとおりです。
通常、データベースエンジンは、ビュー定義から1つのベーステーブルへの変更を明確に追跡できる必要があります。
クエリプロセッサの制限により、ビューが技術的に更新可能であっても、実際には実際には更新できないことに注意してください。推論。それは、「...データベースエンジンが...できる必要がある」というフレーズの背後にある微妙な点です。
ビューが実際に更新可能であることを確認する最も簡単な方法は、更新クエリの実行前(「推定」)プランを要求することです。エラーが発生した場合は、ビューが論理的に更新可能でないか、クエリプロセッサが更新可能であると判断できません。
「見積もられた」計画の要求には、当然、クエリの実行は含まれません。表示されているプランは、クエリオプティマイザが削除できたビュー定義の量も示しています(冗長であるため)。通常、これは適切に機能するため、更新ビューのプランは、影響を受ける単一のベーステーブルへの単純な更新のプランと非常によく似ています。
リンクテーブルdimClaimStatusのClaimStatusName列を使用して、外部キーを介して参照されるメインテーブルを更新できますか? [...] tabDataのfiClaimStatusを変更したい。
投稿したクエリを使用しない:
update claims
set status='Awaiting Auth.'
where status = 'Approved'
これにより、ビューの公開された列名statusに関連付けられたベーステーブル列が変更されます。ビュー定義から、これはテーブルdimClaimStatusの列ClaimStatusNameのエイリアスです。
実行プランは、dimClaimStatusがビューを通じて更新されたテーブルであることを示しています。
fiClaimStatus
を更新する場合は、updateステートメントで指定する必要がある列です。それがルックアップを含む場合、最初に望んだようにビューを直接使用できない可能性がありますが、次のようなものを書くことができます:
update claims
set fiClaimStatus =
(
select CS.idClaimStatus
from dbo.dimClaimStatus AS CS
where CS.ClaimStatusName = 'Awaiting auth.'
)
where status = 'Approved';`
あなたのUPDATEがあなたのビューのFROM句でs
を更新していると想像してください。次に、私が最近書いたこのブログを読んで、どのように影響を受けるかを確認してください。
http://blogs.lobsterpot.com.au/2016/01/12/join-effects-with-update/
更新可能なビューのルール を破っていないと仮定すると、問題はありません。また、私の投稿の内容にも注意してください。
state
内の列view
を更新します。ビュー内でs.ClaimStatusName AS [Status]
を参照します。 view
のコードから、dimClaimStatus
テーブル(dimClaimStatus AS s
)を更新していることがわかります。
2つの列idClaimStatus
とClaimStatusName
があることを確認すると、テーブルのID\Name構造があります。ビュー内にClaimStatusName
を表示します。
したがって、dimClaimStatus
テーブル内の名前を更新します。これが(1 row(s) affected)
の理由です。
ビューを更新すると、ビュー内の複数の行内に新しい文字列が表示されます。