2015-01-05 3 views
1

Я хочу проверить, существует ли конкретный вид перед его запросом. Я использую динамический 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, но не повезло. Я также пробовал решение в: How to check the existence of a view, но в какой-то момент мне нужно указать имя вида в моем запросе, и он будет жаловаться

Любая информация была бы принята с благодарностью!

ответ

1

Проверьте наличие вида за пределами динамический 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(), потому что вы можете передать переменные и из.

EDIT:

В этом случае, вы, по сути должны сделать динамический 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); 
+0

Спасибо за ответ. Тем не менее, я должен извиниться, поскольку оставил важный пункт. Я буду предоставлять базу данных sys.views в предложении FROM. В результате я использовал динамический SQL для запроса (я отредактировал свой исходный вопрос) – alpha

+0

Я считаю, что ваш ответ указывает мне в правильном направлении! Мне просто нужно поиграть с одиночными кавычками, чтобы скомпилировать его. Большое спасибо. – alpha

0

Вы можете использовать условие 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) 
+0

Я просто попробовал ваше предложение. Тем не менее, я по-прежнему получаю ту же ошибку. Компилятору не нравится тот факт, что я ссылаюсь на представление (@viewName), которого не существует (строка 6 в вашем коде). – alpha

0

Какая версия SQL Server вы используете? Я имею только 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; 
0

Остерегайтесь, если ваш взгляд находится в другой схеме, потому что тогда вам нужно также проверить SCHEMAS таблицу:

SELECT 1 FROM SYS.VIEWS 
INNER JOIN SYS.SCHEMAS ON SYS.SCHEMAS.schema_id = SYS.VIEWS.schema_id 
WHERE SYS.VIEWS.TYPE='V' 
    AND [email protected]_Schema_Name 
    AND [email protected]_View_Name 
Смежные вопросы