捕获更新/插入视图的计算列

时间:2013-03-22 20:29:32

标签: sql sql-server view sql-server-2008-r2 calculated-columns

我正在使用SQL Server 2005/2008 R2

我的SQL脚本是:

UPDATE MyView 
SET MyColumn = 'My new value' 
WHERE ID = 7

错误消息:

  

Msg 271,Level 16,State 1,Line 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'`

此外,我找不到返回脚本中与“计算列”或“联合结果”操作有关的任何字段。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

不是它对您有所帮助,但如果您正在运行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 =表中的列”对象,它可以正常工作。