我继承了一个拥有数千个视图的大型数据库项目。
许多观点是无效的。它们引用不再存在的列。一些视图非常复杂并且引用了许多列。
有没有一种简单的方法可以追踪所有不正确的列引用?
我继承了一个拥有数千个视图的大型数据库项目。
许多观点是无效的。它们引用不再存在的列。一些视图非常复杂并且引用了许多列。
有没有一种简单的方法可以追踪所有不正确的列引用?
已更新以检索错误详细信息
所以这个答案可以让你得到你想要的,但它不是最好的代码。
使用游标(是的,我知道 :))SELECT
从 TRY 块中的每个视图执行 a 以查找失败的视图。注意我用SELECT * INTO #temp FROM view X WHERE 1 = 0
this 包装每个语句是为了停止EXEC
返回任何结果,而 1=0 是为了让 SQL Server 可以优化查询,使其实际上是一个 NO-OP。
然后,我返回 sql 失败的所有视图的列表。
我没有对此进行大量测试,但它似乎有效。我想摆脱视图中每个 SELECT 的执行。
所以这里是:
DECLARE curView CURSOR FOR
SELECT v.name AS ViewName
FROM sys.views v
INNER JOIN sys.sql_modules m
on v.object_id = m.object_id
OPEN curView
DECLARE @viewName SYSNAME
DECLARE @failedViews TABLE
(
FailedViewName SYSNAME,
ErrorMessage VARCHAR(MAX)
)
FETCH NEXT FROM curView
INTO @ViewName
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
exec ('SELECT * INTO #temp FROM ' + @viewName + ' WHERE 1=0' )
END TRY
BEGIN CATCH
INSERT INTO @failedViews VALUES (@viewName, ERROR_MESSAGE())
END CATCH
FETCH NEXT FROM curView
INTO @ViewName
END
CLOSE curView
DEALLOCATE curView
SELECT *
FROM @failedViews
返回的错误示例如下:
FailedViewName ErrorMessage
--------------- -------------
vwtest Invalid column name 'column1'.
sys.views
此答案通过查看,sys.columns
和sys.depends
(如果列已被别名,则获取基础列)找到最初在视图中定义的基础列。INFORMATION_Schema.VIEW_COLUMN_USAGE
然后,它将其与包含当前列使用情况的数据进行比较。
SELECT SCHEMA_NAME(v.schema_id) AS SchemaName,
OBJECT_NAME(v.object_id) AS ViewName,
COALESCE(alias.name, C.name) As MissingUnderlyingColumnName
FROM sys.views v
INNER JOIN sys.columns C
ON C.object_id = v.object_id
LEFT JOIN sys.sql_dependencies d
ON d.object_id = v.object_id
LEFT JOIN sys.columns alias
ON d.referenced_major_id = alias.object_id AND c.column_id= alias.column_id
WHERE NOT EXISTS
(
SELECT * FROM Information_Schema.VIEW_COLUMN_USAGE VC
WHERE VIEW_NAME = OBJECT_NAME(v.object_id)
AND VC.COLUMN_NAME = COALESCE(alias.name, C.name)
AND VC.TABLE_SCHEMA = SCHEMA_NAME(v.schema_id)
)
对于以下视图:
create table test
( column1 varchar(20), column2 varchar(30))
create view vwtest as select column1, column2 as column3 from test
alter table test drop column column1
查询返回:
SchemaName ViewName MissingUnderlyingColumnName
dbo vwtest column1
这是在此答案的帮助下开发的
您可以使用系统表获取信息。
SELECT v.VIEW_NAME,v.TABLE_CATALOG,v.TABLE_SCHEMA,v.TABLE_NAME,v.COLUMN_NAME
from INFORMATION_SCHEMA.VIEW_COLUMN_USAGE v
left outer join INFORMATION_SCHEMA.COLUMNS c
ON v.TABLE_CATALOG=c.TABLE_CATALOG AND v.TABLE_SCHEMA=c.TABLE_SCHEMA AND v.TABLE_NAME=c.TABLE_NAME AND v.COLUMN_NAME=c.COLUMN_NAME
WHERE c.TABLE_NAME IS NULL
ORDER BY v.VIEW_NAME