SQL Server 2008 - sp_refreshview轰炸一些视图

时间:2011-06-23 20:47:09

标签: sql-server views

我继承了一个相当重要的项目,它广泛使用了SQL Server(2005和2008)视图。

构建过程的一个步骤是调用sp_refreshviews系统存储过程,以确保没有任何表的更改破坏了我们的视图。这很好....除了大约三四个(200多个)视图....

对于那些,它只是炸弹 - 给出奇怪的错误消息,如

  

Msg 15165,Level 16,State 1,   程序   sp_refreshsqlmodule_internal,第55行   找不到对象   'vYourViewNameHere'或者你没有   得到许可。

这是错误的 - 视图确实存在,我绝对可以从中进行选择。

我似乎找不到任何有关为什么这种情况的简明信息,触发它的原因......任何想法?我能做些什么来发现这些有问题的观点吗?我可以更改他们的definitino,以便他们可以再次刷新吗?

更新:我在Microsoft Connect上记录了一个错误报告 - 如果您同意这看起来很奇怪并需要修复,请投票支持!

https://connect.microsoft.com/SQLServer/feedback/details/676728/sp-refreshview-crashes-with-misleading-error-on-views-with-schemabinding

4 个答案:

答案 0 :(得分:15)

我在评论中注意到你提到它有SCHEMABINDING。我几乎可以保证这就是问题所在。 Books online具体说明这是用于非架构绑定视图。

方案绑定视图不允许发生重大更改,因此更新元数据是不必要的。你可以安全地跳过它。

您可以识别所有模式绑定视图,如下所示:

SELECT * FROM sys.views WHERE OBJECTPROPERTY(object_id, 'IsSchemaBound')=1

答案 1 :(得分:5)

使用sp_helptext时遇到了同样的错误。在我的情况下,原因是使用sp_rename重命名视图。以下代码重现此错误。

create view demo as select dummy = 1
go

exec sp_rename 'demo', 'new_demo'
go

exec sp_refreshview 'new_demo'
go

唯一的解决方案是手动更改视图。将此修复程序应用于上述解决方案,您将获得:

create view demo as select dummy = 1
go

exec sp_rename 'demo', 'new_demo'
go

-- This statement fixes the problem
alter view new_demo as select dummy = 1
go

exec sp_refreshview 'new_demo'
go

答案 2 :(得分:0)

我对此错误的体现是:

  

消息8116,级别16,状态1,过程sp_refreshsqlmodule_internal,   第75行参数数据类型int对于子字符串的参数1无效   功能

此错误消息正在db脚本中的各个位置报告。我会说错误的地方。如果我注释掉SQL报告的错误,则会在其他地方报告相同的错误。

我在脚本中注释了以下调用作为解决方法,脚本将成功完成。

-- EXECUTE sp_refreshview @viewName;

注意:我的数据库在运行RThomas'中建议的查询时,没有报告具有模式绑定视图。相邻答案https://stackoverflow.com/a/6460532/179972

更新 - 解决方案:

在我们的数据库脚本成功运行并注释掉sp_refreshview命令后(如上所示),然后我们自己运行了视图刷新代码,它也成功了。

-
这个答案对我如何能够成功运作没有意义,但是我在这里记录它以防它对其他人有帮助。

答案 3 :(得分:0)

要查找哪个视图是您的问题,请在普通sppRefreshViews中添加打印件。没有什么东西在这里破碎,但我想我会分享。

CREATE procedure sppRefreshViews2

    as
    declare @t varchar (1024)

    declare tbl_cur cursor for
    select TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW' and table_name like 'sp%'
    OPEN tbl_cur

    FETCH NEXT from tbl_cur INTO @t
    WHILE @@FETCH_STATUS = 0
    BEGIN
    print      @t 
    exec ('sp_refreshview ''' + @t + '''')
    FETCH NEXT from tbl_cur INTO @t
    END

    CLOSE tbl_cur
    DEALLOCATE tbl_Cur