2

我有一个非常奇怪的问题,我可以重现该视图。我很确定某些视图元数据不是最新的并导致此问题...

简而言之:

  • 我有一个视图(MyTestView)。
  • 此视图已重命名 (MyTestViewOld)。
  • 使用重命名视图的原始名称和不同的选择查询 (MyTestView) 创建一个新视图。
  • sp_refreshview 在重命名的视图 (MyTestViewOld) 上执行。
  • 现在 MyTestView 的实现就是 MyTestViewOld 的实现!

我尝试查看 SP sp_refreshview,但他只是执行了另一个名为 sp_refreshsqlmodule_internal 的 SP。我在主数据库的系统存储过程中没有看到这个视图:(

我的问题实际上是通过删除“MyTestViewOld”来解决的,但我想知道到底发生了什么!肿瘤坏死因子

这里是重现问题的脚本!(请按步骤执行)

--create a test table
create table dbo.MyTestContacts(
    [Title] [varchar](20) NULL,
    [Name] [varchar](255) NULL,
    [FirstName] [varchar](255) NULL,
    [Telephone] [varchar](50) NULL,
    [Email] [varchar](255) NULL
    )

--insert data in the temp table
insert dbo.MyTestContacts values ('Mr', 'Holly', 'Buddy', '0123456798', 'buddy@holly.co')
insert dbo.MyTestContacts values ('Mr', 'Valens', 'Ritchie', '987654312', 'ritchie@valens.co')
insert dbo.MyTestContacts values ('Mr', 'Richardson', 'Jiles Perry', '987654312', 'jp@richardson.co')


--create a view
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create view dbo.MyTestView as 
select Title, Name, FirstName from dbo.MyTestContacts
GO


--do a SCRIPT VIEW AS / ALTER TO in sql management studio to verify the view implementation


--rename the view
exec sp_rename 'dbo.MyTestView', 'MyTestViewOld'


--BIS1 (explained below; used in a 2nd test run)


--create a view with the same name as the first view, but different implementation!
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create view dbo.MyTestView as 
select Title, Name, FirstName, Telephone from dbo.MyTestContacts
GO


--do a SCRIPT VIEW AS / ALTER TO in sql management studio to verify the view implementation of MyTestView (telephone is added)


--perform a refreshView action on the MyTestViewOld view
exec sp_refreshview 'dbo.MyTestViewOld'


--do a SCRIPT VIEW AS / ALTER TO in sql management studio to verify the view implementation of MyTestView --> THIS SHOWS THE MyTestViewOld IMPLEMENTATION!!!!


--(BIS1) Note that this sequence gets broken when I do an ALTER VIEW on MyTestViewOld right after the rename!
--SET ANSI_NULLS ON
--GO
--SET QUOTED_IDENTIFIER ON
--GO
--alter view dbo.MyTestViewOld as 
--select FirstName, Name, Email, Telephone from dbo.MyTestContacts
--GO


--drop everything
drop view dbo.MyTestViewOld
drop view dbo.MyTestView
drop table dbo.MyTestContacts
4

2 回答 2

1

sp_rename相当不完善,并且有很多警告不要在大多数对象类型上使用它:

更改对象名称的任何部分都可能破坏脚本和存储过程。我们建议您不要使用此语句重命名存储过程、触发器、用户定义的函数或视图;相反,删除对象并使用新名称重新创建它。

虽然没有关于您发现的场景的具体警告,但有一些关于导致问题出现的潜在路径的线索:

重命名存储过程、函数、视图或触发器不会更改sys.sql_modules目录视图定义列中对应对象名称的名称

而且,正如您所发现的,刷新视图的内部方法是sp_refreshsqlmodule_internal- 所以我建议它是“模块”级别元数据内部的某种形式的错误。

您可能需要考虑在SQL Server Connect上提出问题,如果没有其他原因,只是将错误记录在其他地方并且(可能)让他们向产品文档添加进一步的警告。

于 2013-07-30T14:19:13.143 回答
0

也遇到了这个问题。我使用以下查询来识别数据库中可能导致问题的任何视图:

select * from (
SELECT o.object_id, o.name, 
Replace(Replace(Replace(SUBSTRING(m.definition,13,(CHARINDEX(CHAR(13),m.definition + CHAR(13)))-13),'[',''),']',''),'dbo.','') as definitionName
FROM sys.objects AS o
left join sys.sql_modules AS m on o.object_id = m.object_id
where o.type='v' )x
where name != definitionName
于 2017-07-17T09:26:25.923 回答