我正在使用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'`
此外,我找不到返回脚本中与“计算列”或“联合结果”操作有关的任何字段。
答案 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 =表中的列”对象,它可以正常工作。