捕获更新/插入视图的计算列[重复]
Posted
技术标签:
【中文标题】捕获更新/插入视图的计算列[重复]【英文标题】:Catch Update/Insert Computed Column of a View [duplicate] 【发布时间】:2013-03-22 20:29:31 【问题描述】:我使用的是 SQL Server 2005/2008 R2
我的 SQL 脚本是:
UPDATE MyView
SET MyColumn = 'My new value'
WHERE ID = 7
错误信息:
消息 271,第 16 级,状态 1,第 1 行 无法修改“MyColumn”列,因为它要么是计算列,要么是 UNION 运算符的结果。
我知道MyColumn
是基表中的一个计算列(比如FullName
是从LastName + ', ' + FirstName
计算出来的)
我的目标是捕获错误,以便脚本继续执行。
我尝试了以下脚本,但没有成功。错误未被捕获:
BEGIN TRY
UPDATE MyView
SET MyColumn = 'My new value'
WHERE ID = 7
END TRY
BEGIN CATCH
-- Error occurred while updating view. The script will keep running
END CATCH
我检查了以下脚本试图解决问题,但没有成功:
脚本 1
SELECT is_computed
FROM sys.columns c, sys.views v
WHERE c.object_id = v.object_id
AND v.name = 'MyView'
前面的脚本为所有结果返回 0(这是不正确的,其中一列是计算列)
脚本 2:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'MyView'`
我也无法从返回的脚本中找到任何与“计算列”或“联合结果”操作有关的字段。
【问题讨论】:
sommarskog.se/error-handling-I.htmlsys.computed_columns
确切地告诉您计算了哪些列 - 只需执行 SELECT Name FROM sys.computed_columns
即可获取计算列的名称
【参考方案1】:
首先,没有系统视图或表可以真正告诉您视图的哪一列是派生列或计算列。它几乎只能在运行时检测到,或者您可以使用 powershell 脚本或其他东西在 SQL 之外检测它。
如果您只想在异常发生后继续执行您的脚本,您可以使用 goto,但这不是一个好习惯。
begin try
select 1/0
end try
begin catch
Print 'error occurred'
goto MarkPoint
end catch
select * from sys.columns
MarkPoint:
select top 1 * from sys.tables
【讨论】:
当然有办法!!有sys.computed_columns
确切地告诉你计算了哪些列......另外,还有一个is_computed
在sys.columns
中的每个条目上也有标志....
无标记,视图字段不会显示为“is_computed = 1”。他们总是0。我在我的问题中提到了这一点。 ljh,错误未捕获。这是我的全部问题。我在问题中提到了这一点。【参考方案2】:
不是说它对你有帮助,但如果你运行的是 SQL Server 2012,你可以运行
sp_describe_first_result_set N'select * from View'
它将提供正确的信息(即 is_updateable 设置为 0,is_computed_column 设置为 1)。
这是一个不完全 100% 可靠的查询,它将返回视图中的所有列,这些列实际上是基表中的计算列:
SELECT c.name FROM sys.objects AS O
INNER JOIN sys.sql_expression_dependencies SED ON SED.referenced_id=O.object_id
INNER JOIN sys.objects O2 ON O2.object_id=SED.referencing_id
INNER JOIN sys.columns c on c.object_id = o.object_id
where
QUOTENAME(O2.name) = 'MyView'
and c.is_computed = 1
它不是 100% 可靠的,因为 sql_expression_dependencies 表不能完全保持最新状态,并且不能完美地“读取”查询(并且它错过了函数调用中的函数调用等内容)但是对于标准"view = columns from a table" 对象,它可以正常工作。
【讨论】:
以上是关于捕获更新/插入视图的计算列[重复]的主要内容,如果未能解决你的问题,请参考以下文章