A quick introduction - I'm James Allison, a developer within the SQL Tools division at Red Gate.
Recently I’ve been working on a new experimental feature for SQL Prompt – Auto Refresh Suggestions.
My goal for this feature has been to reduce the number of times users are required to manually refresh SQL Prompt's suggestions. SQL Prompt stores its own internal representation of a database when it first loads it. However, if a change is made to a database after it's been loaded, SQL Prompt's suggestions and expansions may be out of date until you manually select the ‘Refresh Suggestions’ option, as shown below:
How does it work?
On enabling the new plugin, a background polling thread is started. Every 10 seconds this performs a couple of inexpensive queries (they typically take 10-20ms to complete) on the sys.objects table of the current query window’s connection. The count and the time of the most recently modified object are retrieved. If either of these is found to have changed since the last check, the Refresh Suggestions command is triggered. We also trigger a refresh of SSMS’s own intellisense to update invalid object red squiggles.
In addition to polling, we’ve also hooked into SSMS’s ‘Execute' (F5) command. After this has been called, the plugin immediately checks to see if SQL Prompt needs to refresh its cache.
Work in progress
It’s probably worth stressing that this is still an experimental feature, so in a few cases it may not catch a change. The plugin currently only monitors the connection from the current query window, which means changes to a cached database other than the one being immediately worked on will not be detected until a query window with a connection to it has focus.
Another issue to be aware of is that not all objects are stored in the sys.objects table. DDL Triggers for instance are not schema scoped, and so are found in sys.triggers. As a result, this feature does not currently detect changes to triggers.
SQL Server 2000 unfortunately doesn’t provide a modified date in its sysobjects table, so we check the create date instead. This means far more modifications won’t be detected on these databases.
If the polling thread throws an exception, its current behaviour is for it to log the error as a warning, and then to silently disable itself. This may happen if the current connection is closed or disconnected.
How could it work differently?
I’d very much welcome any feedback you may have on how you’d like this feature to be implemented. Ideally I’d like to keep configuration as clean and as straight forward as possible whilst providing the best balance between performance and accuracy.
Below I’ve listed a number of changes I’m considering. If you have any comments on these, or additional options I’ve not listed, please let us know!
Poll different sources:
The Default Trace: Enabled by default in SQL Server since 2005, the default trace provides a more complete and reliable source of information, but comes with an associated performance cost.
The sys.triggers table: Polling this in addition to sys.objects will enable us to detect changes to triggers.
Polling frequency:
We could poll more often to detect changes earlier – or less often to reduce server load.
Command hooks:
In addition to polling, we also check if we need to refresh whenever the execute command is used in SSMS. This makes many updates instantaneous, but doesn’t cover the other ways you could change the schema in SSMS – such as column renaming from the Object Explorer, or saving changes to a table design. It could be worth hooking into these events too.
Databases to check:
The current behaviour is only to check the database connected to by the current query window for changes. This could be changed to poll all the loaded databases to ensure suggestions are up to date, though this would be a little more expensive.