Tim*_*ter 6 sql-server-2005 sql-server t-sql view update
由于 MSDN 没有说太多,如果我执行以下查询会发生什么?
update claims set status='Awaiting Auth.'
where status = 'Approved'
Run Code Online (Sandbox Code Playgroud)
我可以使用ClaimStatusName链接表的列dimClaimStatus来更新通过外键引用的主表吗?
视图本身查询多个表,主表是tabData,我也想用上面的查询更新。我想改变fiClaimStatus在tabData从FK该手段 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
Run Code Online (Sandbox Code Playgroud)
由于该表包含 2000 万条客户记录,我想在执行它之前先知道会发生什么。在评论和回答之后,我现在已经执行了。直接结果是:
(1 row(s) affected)
Run Code Online (Sandbox Code Playgroud)
这是令人惊讶的,因为在这种状态下有数千条记录,现在似乎正在更新。
实际上它没有按预期工作并且可疑(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')
Run Code Online (Sandbox Code Playgroud)
CREATE VIEW (Transact-SQL)文档的关键部分是:
通常,数据库引擎必须能够清楚地跟踪从视图定义到一个基表的修改。
请注意,即使视图在技术上是可更新的,但由于查询处理器推理的限制,它实际上可能无法更新。这就是短语背后的微妙之处,“...数据库引擎必须能够...”
确保视图实际上可更新的最简单方法是为更新查询请求执行前(“估计”)计划。如果出现错误,要么视图在逻辑上不可更新,要么查询处理器无法判断它是。
自然地,请求“估计”计划不涉及执行查询。显示的计划还将显示查询优化器能够删除多少视图定义(因为它是多余的)。通常,它在这方面做得很好,因此更新视图计划可能看起来非常类似于对单个受影响的基表进行简单更新的计划。
我可以使用链接表dimClaimStatus的ClaimStatusName列更新通过外键引用的主表吗?[...] 我想更改tabData中的 fiClaimStatus。
不使用您发布的查询:
update claims
set status='Awaiting Auth.'
where status = 'Approved'
Run Code Online (Sandbox Code Playgroud)
这会更改与视图的公开列名称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';`
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11866 次 |
| 最近记录: |