查询之前检查View是否存在

Check if View exists before querying it

我想在查询特定视图之前检查它是否存在。我使用动态 SQL 创建查询:

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)

所以只要@viewName 实际存在,一切都正常。但是,如果@viewName 是 sys.views 中不存在的视图,我会从编译器中得到一个错误:

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.

本来以为既然用了IF语句,直接跳过了View的查询。但是,似乎 View has 存在,否则我会收到上述错误。

我尝试过替代解决方案,例如使用字符串作为视图名称,但没有成功。我也尝试过以下解决方案:How to check the existence of a view,但有时我必须在查询中引用视图名称,它会报错

任何信息将不胜感激!

检查动态 外部 视图是否存在 SQL。您正在尝试防止 select 中不存在的视图的编译时错误。 if:

没有问题
IF EXISTS(SELECT 1 FROM sys.views WHERE name = @viewName)
BEGIN
    SET @sqlCommand = 'SELECT * FROM ' + @viewName
    EXEC(@sqlCommand)
END;

虽然在这种情况下没有区别,但如果您使用的是动态 SQL,请了解 sp_executesql -- 它比 exec() 更强大,因为您可以传入和传出变量。

编辑:

在那种情况下,您基本上必须在动态 SQL 中执行动态 SQL。以下未测试,因此可能存在语法错误:

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);

当不存在时可以使用Else条件来设置错误信息

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)

您使用的 SQL 服务器是什么版本?我只有 SQL Server 2014 可用于测试,但下面的 T-SQL 适用于缺失和非缺失视图。我想知道您正在检查 otherdb.sys.views 中是否存在视图但在从视图中选择时没有限定 otherdb 是否是罪魁祸首?

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;

当心你的视图是否在不同的架构中,因为那样你还需要检查 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