Reputation: 13
I want to check if a specific View exists before querying it. I use dynamic SQL to create the query:
DECLARE @sqlCommand varchar(1000)
DECLARE @viewName varchar(1000)
DECLARE @otherDB varchar(1000)
SET @sqlCommand = 'IF EXISTS(SELECT 1 FROM ' + @otherDB + '.sys.views WHERE name=''' + @viewName + ''')
BEGIN
SELECT * FROM ' + @viewName + '
END'
EXEC (@sqlCommand)
So everything works fine as long as @viewName actually exists. However, if @viewName is a View that does not exist in sys.views, I get an error from the compiler:
The OLE DB provider "SQLNCLI11" for linked server "server" does not contain the table @viewName. The table either does not exist or the current user does not have permiossions on that table.
I would have thought that since an IF statement is used, it would just skip the querying of the View. However, seems like the View has to exist otherwise I get the above error.
I've tried alternate solutions, such as using strings for the View names, but no luck. I've also tried the solution in: How to check the existence of a view, but at some point I have to reference the View name in my query, and it would complain
Any info would be greatly appreciated!
Upvotes: 1
Views: 3189
Reputation: 1048
Beware if your view is in a different schema, because then you need to also check the SCHEMAS table:
SELECT 1 FROM SYS.VIEWS
INNER JOIN SYS.SCHEMAS ON SYS.SCHEMAS.schema_id = SYS.VIEWS.schema_id
WHERE SYS.VIEWS.TYPE='V'
AND SYS.SCHEMAS.NAME=@Your_Schema_Name
AND SYS.VIEWS.NAME=@Your_View_Name
Upvotes: 0
Reputation: 2293
What version of SQL Server are you using? I only have SQL Server 2014 available to test with, but the T-SQL below works for both missing and not missing views. I wonder whether the fact that you are checking for existence of the view in otherdb.sys.views but are not qualifying otherdb when selecting from the view is to blame?
declare @viewName varchar(50) = 'MissingView';
declare @sqlCommand nvarchar(1000);
declare @otherdb varchar(20) = 'MyTestDatabase';
set @sqlCommand = N'if exists
(
select 1
from ' + @otherdb + '.sys.views as v
where v.name = ''' + @viewName + '''
)
begin
select * from ' + @otherdb + '.dbo.' + @viewName + ';
end
else
begin
select ''Nah mate - missing view'';
end';
print @sqlCommand;
execute sp_executesql @sqlCommand;
Upvotes: 1
Reputation: 1269953
Check for the existence of the view outside the dynamic SQL. You are trying to prevent the compile-time error of the view not existing in the select
. There is no issue with the if
:
IF EXISTS(SELECT 1 FROM sys.views WHERE name = @viewName)
BEGIN
SET @sqlCommand = 'SELECT * FROM ' + @viewName
EXEC(@sqlCommand)
END;
Although it doesn't make a difference in this case, if you are using dynamic SQL, learn about sp_executesql
-- it is more powerful than exec()
because you can pass variables in and out.
EDIT:
In that case, you essentially have to do dynamic SQL inside dynamic SQL. The following is not tested, so there could be a syntax error:
DECLARE @viewName varchar(1000);
DECLARE @otherDB varchar(1000);
declare @sql nvarchar(max) = '
IF EXISTS (SELECT 1 FROM @otherDB.sys.views WHERE name = ''@viewName'')
BEGIN
DECLARE @sqlCommand nvarchar(max);
SET @sqlCommand = ''SELECT * FROM @viewName'';
EXEC(@sqlCommand);
END;';
SET @sql = replace(replace(@ql, '@otherDB', @otherDB), '@viewName', @viewName);
EXEC(@sql);
Upvotes: 2
Reputation: 8497
You can use the Else condition when not exists to set error message
DECLARE @sqlCommand varchar(1000)
DECLARE @viewName varchar(1000)
SET @viewName = 'vwName'
SET @sqlCommand = 'IF EXISTS(SELECT 1 FROM sys.views WHERE name=''' + @viewName + ''')
BEGIN
SELECT * FROM ' + @viewName + '
END
ELSE
BEGIN
SELECT ''View not exists''
END
'
EXEC (@sqlCommand)
Upvotes: 0