捕获更新/插入视图的计算列[重复]

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.html sys.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_computedsys.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" 对象,它可以正常工作。

【讨论】:

以上是关于捕获更新/插入视图的计算列[重复]的主要内容,如果未能解决你的问题,请参考以下文章

计算重复列并更新计数器列

通过在 MYSQl 中更新其值来插入重复行

从内部连接更新列[重复]

sql合并重复的字段

mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法

更新视图中的重复值以使其唯一