If you rename a view through the interface in SQL server, it can lead to strange behaviour later on if you ever come to recompile the view. Symptoms include views failing to recompile and, in extreme cases, the entire structure of a view (not necessarily the one you're recompiling) changing when the built-in sp_refreshview
procedure is run.
Behind the scenes, SQL Server stores information about the views in its system tables; the key one for our purposes here is Information_Schema.Views
, which includes, among other things, the view's name and its SQL definition, something like the example below:
Name |
Definition |
vieContacts |
Create View vieContacts as Select ContactID, Name, PhoneNumber from ContactsTable
|
Now, suppose I rename vieContacts
in the interface to OldVieContacts
. This will update the name in the system table, but does not update the definition, so I end up with the following:
Name |
Definition |
OldVieContacts |
Create View vieContacts as Select ContactID, Name, PhoneNumber from ContactsTable
|
When I come to recompile the view, it will fail, giving me the error "Msg 208, Level 16, State 6, Procedure sp_refreshsqlmodule_internal, Line 75
Invalid object name 'vieContacts'.
" This is because the name doesn't match what is stored in the definition.
Unfortunately, the problem doesn't stop there. If I use the copy/paste funtion in SQL Managent Studio, I can copy a view, rename it so that it's a backup and then edit my original. This sounds like a good idea, but because of the problems that renaming causes, it can lead to major headaches later on. To illustrate why this can be so confusing, let's imagine I copy my vieContacts, rename the copy to OldVieContacts and modify my vieContacts to include another couple of fields. After this, I would have the following in Information_Schema.Views
:
Name |
Definition |
OldVieContacts |
Create View vieContacts as Select ContactID, Name, PhoneNumber from ContactsTable
|
vieContacts |
Create View vieContacts as Select ContactID, Name, PhoneNumber, Address, Email from ContactsTable
|
What makes this such a potential problem is that if I recompile OldVieContacts (and this might be done as part of a script that refreshes all the views) the inbuilt function reads the definition out of Information_Schema.Views
, which tells it to rebuild vieContacts, so the result is that vieContacts gets overwritten and I would see my two new columns disappear from it. Worse, the refresh process also updates the definition in Information_Schema.Views
, so now vieContacts would be stuck with the incorrect structure and no easy way to fix it.
So what can you do about these problems? Well, here are some suggestions:
- Prevention is better than cure. Don't rename views thorugh the SQL Management Studio interface.
- If you need to change the name of the view, drop the view and recreate it with the new name - you can use the "Script View As" option to create a SQL script that will do the drop and create for you, and you can just change the name in the script for the creation before running it.
- If you're lucky, you may be able to rename the view in the interface back to its old name. This isn't recommended though as it's not as sure as other methods.
- Rather than copying a view, just copy the SQL definition from the designer into a new blank view. This may seem more complex than just copying & pasting the view, but it will be better in the long term
- If you suspect that some of your views may suffer from this issue, you can check to see how severe the problem is by running this SQL command from a query window:
Select TABLE_NAME, VIEW_DEFINITION from INFORMATION_SCHEMA.VIEWS where VIEW_DEFINITION not like '%' + TABLE_NAME + '%'
- this will identify the views that need attention.
- You can repair a view that has suffered in this way by running an
Alter View
script to alter the view to the correct definition.
The best thing, though, is to avoid renaming views through the SQL Server Management Studio interface.