"If at first you don't succeed..."
Apparently the cool new conclusion to this motto is
"throw your hands in the air and panic". This is certainly how the SQL 2008 Management Studio reacts when it encounters a problem enumerating object explorer information for one or more databases on a server. I recently installed the SQL 2008 tools and was quite surprised to encounter an error dialog following my first actions. I connected to a server that contains several databases, only a few of which I have rights to access. Upon expanding the Databases node in the Object Explorer window, I received the following error:
Failed to retrieve data for this request. (Microsoft.SqlServer.Management.Sdk.Sfc)
Additional information:
An exception occured while executing a Transact-SQL statement or batch.
(Microsoft.SqlServer.ConnectionInfo)
The server principal "MyServerPrincipal" is not able to access the database "FirstDBInList" under the current security context. (Microsoft SQL Server, Error: 916)
Yikes! I know that I don't have access to
FirstDBInList but I'm unsure as to why that would stop me from enumerating the databases on the server. Typically I'm allowed to at least see the list so that I can interact with my database via that window. I am unable to perform any operations on the databases to which I don't have rights but that shouldn't stop me from interacting with the databases for which I have been granted permissions.
What's the problem?
Then a little bell rung in my head. I'd seen this before. I remember this from the SQL 2000 days. A little googling turned up
this great article by
Aaron Bertrand. It turns out that the
Object Explorer Details window is part of the problem. Whereas the Object Explorer window only shows the familiar list of nodes, the
Object Explorer Details window attempts to go one step further and show additional information about each database. However, in order to show that information the studio attempts to connect to each of the databases in the list. If the current user does not have rights to one or more of those databases and they are configured to auto-close (as many are in many environments) then studio will panic after it is unable to retrieve the information it requested. Instead of degrading gracefully and graying out the node or simply moving onto the next database in the list, it simply halts all operations and throws up the error dialog seen above. Not very shiny! Remember too that this is the SQL 2008 Management Studio in its
default configuration. Not exactly an edge case.
How do I fix it?
In order to fix the issue we simply need to tell studio to not query the databases for information it won't be able to retrieve. It turns out that the offender in this case is "Collation", or rather that studio is unable to determine the state of collation on databases to which appropriate rights have not been granted. The following steps can be used to achieve this.
First, open the
Object Explorer Details pane either by clicking
View->Object Explorer Details or by pressing
F7. Then double click
Databases in the right-hand pane. Finally right-click the bar showing the column headers and uncheck Collation. You can now close the
Object Explorer Details pane, right-click
Databases in the regular
Object Explorer pane and select
Refresh. The node should now expand as expected.
Why did that work?
This solution works for the following reasons. The
Object Explorer Details (OED) pane is used to show additional information about entities on a server. The column headers in the
Databases view of OED each show a particular piece of information for each database on the server. When the Databases node in the regular Object Explorer pane is expanded, the management studio attempts to query for the information for each of these selected column headers just in case the OED pane will be shown. However, if the current user does not have rights to query for that information on one of the databases then an error is thrown and processing stops. This has the unfortunate side-effect of also stopping the enumeration of the databases in the regular Object Explorer window. By removing the Collation column from the OED view, we effectively removed the check for collation settings when enumerating the list of databases. The other default columns all represent data that can be queried even on databases for which the current user does not have rights. However, if you find that the error resurfaces, try removing all of the other column headers from this view.
What can we learn from this?
This illustrates a larger programming principal, one that is often ignored to the detrement of many software packages; error handling and graceful degradation.
It is great that enumerating the data for the Object Explorer window also queries for information that the OED window might need. However, it is not so great that a failure in the additional "helpful" task causes the originally requested operation to fail. As a user the first assumption when encountering an error is that the current action being performed is responsible, not that some helpful side task was the culprit. If helpful additional tasks are going to be performed, then wrap them in a layer of safety, have them handle their errors completely and get out of the way of the main task if they encounter a problem.
The second principal here is that of graceful degradation. Often programs will show an error dialog or even quit completely when they run into a problem. However, in many cases there is no need for such an abrupt halt. The areas of the application that were of importance to the user might be completely unaffected by the problem that occured. In the case of this management studio problem the user could have continued working quite happily without knowing whether collation was enabled for databases that they don't even have access rights to.
Conclusion
Throwing an exception and halting all processing in this case is a bit like taking the football home from the park just because you fell and scraped your knee. It didn't make you many friends as a young MS-DOS program and it won't as an adult enterprise management application either. Play nice...try, catch, and throw like the rest of the kids and leave the drama at home.