Updating a view on multiple joined tables
General view updatability
The key part of the CREATE VIEW (Transact-SQL)
documentation is:
Generally, the Database Engine must be able to unambiguously trace modifications from the view definition to one base table.
Note that even if the view is technically updatable, it may not be actually updatable in practice, due to limitations of the query processor's reasoning. That is the subtlety behind the phrase, "...the Database Engine must be able to..."
The easiest way to be sure that a view is actually updatable is to request a pre-execution ("estimated") plan for the update query. If you get an error, either the view is not logically updatable, or the query processor can't tell that it is.
Requesting a "estimated" plan does not involve executing the query, naturally. The plan shown will also show you how much of the view definition the query optimizer was able to remove (because it is redundant). Typically, it does a good job with this, so the update view plan may look very similar to a plan for a simple update to the single affected base table.
Specific example
Can I use the ClaimStatusName column of the linked table dimClaimStatus to update the main table that is referenced via foreign-key? [...] I want to change fiClaimStatus in tabData.
Not using the query you posted:
update claims
set status='Awaiting Auth.'
where status = 'Approved'
This changes the base table column associated with the view's exposed column name status. From the view definition, that is the alias for column ClaimStatusName in table dimClaimStatus.
The execution plan shows that dimClaimStatus is the table updated through the view:
If you want to update fiClaimStatus
, that is the column you need to specify in the update statement. If that involves a lookup, chances are you can't use the view directly, as you originally wanted, but you could write something like:
update claims
set fiClaimStatus =
(
select CS.idClaimStatus
from dbo.dimClaimStatus AS CS
where CS.ClaimStatusName = 'Awaiting auth.'
)
where status = 'Approved';`
Imagine your UPDATE is updating s
with the FROM clause of your view. Then read this blog I wrote recently to see how it could be affected.
http://blogs.lobsterpot.com.au/2016/01/12/join-effects-with-update/
Assuming you're not breaking the rules for updateable views, then you should be okay. Just also be wary of the things in my post.
You update column state
inside the view
. It refferences s.ClaimStatusName AS [Status]
inside the view. From the code of the view
we see that you update dimClaimStatus
table (dimClaimStatus AS s
).
Seeing that you have 2 columns idClaimStatus
and ClaimStatusName
you have ID \ Name structure of the table. Inside the view you show ClaimStatusName
.
So you update name inside dimClaimStatus
table. This is the reason for (1 row(s) affected)
.
When you refresh the view you see new string inside multiple rows inside the view.