Today I’ve found with my Italian collegues a “nice” bug that made us and the customer mad for several hours.
The problem is related to sp_rename usage and sp_refreshview.
If you have a view like this one
create view dbo.a
as
select c = 1
go
and for any reason someone renames it (for example because he wants to change the view but don’t want to drop the old one, so it rename to something like myview_old):
exec sp_rename 'a', 'b'
go
create view dbo.a
as
select c = 2
go
If you do, everything still works perfectly:
select * from dbo.a
select * from dbo.b
go
And now the “magic”: try to use the refreshview procedure on the “b” view
sp_refreshview 'dbo.b'
go
and voilà, the view “a” will be changed back to the orginal script! If you execute
select * from dbo.a
go
you will get the same result of the view “b”. That’s magic, isn’t it?
And and it’s not only a problem of results. If you open the view “a” you will see that its body has been changed into the body of view “b”!!!
I’ve tested the bug on SQL Server 2005, SQL Server 2008 and SQL Server 2008 R2.
To be honest is not something dangerous, and it should not harm anyone, but just know that if sometimes you have your views reset back to a previous situation, you may well be in the same situation we’ve experienced. Unfortunately there is no way to “detect” this problem even using SQL Profiler or even DDL Events since no “ALTER VIEW” (nor DROP VIEW followed by CREATE VIEW) gets fired in the sp_refreshview process.
There is a workaround to fix it? Of course the answer is yes :)
Just alter the “b” view manually and everything will be fixed:
alter view dbo.b
as
select c = 1
go
from now on the sp_refreshview will work correctly [:)] Just keep it in mind.