I have several databases that each have a table called, say, products.
One of these databases (the “master”) contains products that should be visible from all databases.
I do this by having an allproducts view as follows:
CREATE VIEW allproducts AS
SELECT col[...] FROM products
UNION ALL SELECT col[...] FROM master.dbo.products;
This works well, except that the master database’s allproducts view needs a definition that doesn’t bring in its own products:
CREATE VIEW allproducts AS
SELECT col[...] FROM products;
To simplify things a little, I’d like to have a common view definition, something like the following:
CREATE VIEW allproducts AS
SELECT col[...] FROM products
UNION ALL SELECT col[...] FROM master.dbo.products
WHERE (DB_NAME() <> 'master');
This works, but I’m concerned about performance. So, is the DB_NAME() function deterministic, and if so, will SQL Server shortcut the entire right side of the UNION ALL based on the comparison?
If DB_NAME() is evaluated for each row of master.dbo.products, is there a cleaner way to do this, or must I maintain separate view definitions?
UPDATE: “All metadata functions are nondeterministic. This means these functions do not always return the same results every time they are called, even with the same set of input values.” – http://msdn.microsoft.com/en-us/library/ms187812.aspx
I found another question where someone had a similar situation and found a reasonable workaround:
So the main part of the question has been answered. Even though DB_NAME() is nondeterministic, the execution plans are the same for calling a deterministic UDF versus calling DB_NAME(), and performance indicates that the DB_NAME() result does short-cut the other branches of the query. Neither are quite as fast as a scalar comparison like “0=1” in the WHERE clause, so even deterministic functions don’t fully optimize the plan. I can live with a UDF, so I’m going to go that direction for this situation.
“All metadata functions are nondeterministic. This means these functions do not always return the same results every time they are called, even with the same set of input values.” –
http://msdn.microsoft.com/en-us/library/ms187812.aspx
I ended up not switching on DB_NAME() and just maintaining two versions of each DDL. Annoying, but even a UDF returning a constant bit value wasn’t as efficient as I hoped.