Как я могу проверить, существует ли представление в базе данных?


127

У меня есть код SQL, который необходимо выполнить, если в базе данных существует определенное представление. Как мне проверить, существует ли представление?

РЕДАКТИРОВАТЬ: Используемая СУБД - Microsoft SQL Server

Ответы:


162

ДЛЯ SQL СЕРВЕРА

IF EXISTS(select * FROM sys.views where name = '')

7
Вы, наверное sys.schema, тоже захотите присоединиться к нам .
Эрик

Ошибка: недопустимое имя объекта sys.views. Я запрашивал главную БД
Steam

Если вы обнаружили, что это означает выбор между CREATE и ALTER для представления (как это сделал я), это не работает для VIEW - вам нужно УДАЛИТЬ VIEW *, а затем СОЗДАТЬ его. IF EXISTS по-прежнему отлично работает для DROPING VIEW, поэтому спасибо! :) * Не забывайте о разрешениях, когда делаете это. ;)
FrostbiteXIII

Попробуй это. если он не существует, создайте представление (просто заглушку), а затем измените эту заглушку, чтобы разместить свои обновления. Таким образом, вам никогда не придется отбрасывать его. structuredsight.com/2014/03/12/non-failing-scripts
kemiller2002

Надо ли в кавычки поставить название проверяемого представления? Иначе это никогда не сработает :)
Reversed Engineer

139

Выше уже указано много способов, но один из моих любимых отсутствует ..

GO
IF OBJECT_ID('nView', 'V') IS NOT NULL
    DROP VIEW nView;
GO

ГДЕ nViewназвание просмотра

ОБНОВЛЕНИЕ 2017-03-25: поскольку @hanesjw предложил отказаться от использования процедуры хранения Pвместо Vвторого аргументаOBJECT_ID

GO
IF OBJECT_ID( 'nProcedure', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.sprocName; 
GO

5
Мне нравится этот. Вы также можете использовать "u" для таблиц.
Филипп Сенн

2
Или «P» для хранимых процедур. ЕСЛИ OBJECT_ID ('dbo.sprocName', 'P') НЕ ЯВЛЯЕТСЯ NULL ПРОЦЕДУРА УДАЛЕНИЯ dbo.sprocName; GO
hanesjw

Я не знаю, был ли это лучший ответ в 2009 году, но похоже, что это произойдет в 2016 году (хотя SQL Server 2016 представляет еще лучший вариант).
Эрик Дж.

1
OBJECT_ID doc msdn.microsoft.com/en-us/library/ms190328.aspx - и этот дает вам все типы объектов: msdn.microsoft.com/en-us/library/ms190324.aspx
Simon_Weaver,

55

Это наиболее переносимый и наименее навязчивый способ:

select
    count(*)
from
    INFORMATION_SCHEMA.VIEWS
where
    table_name = 'MyView'
    and table_schema = 'MySchema'

Изменить: это работает на SQL Server, и вам не нужно присоединяться, sys.schemasчтобы получить схему представления. Это менее важно, если все в порядке dbo, но если вы хорошо используете схемы, вам следует помнить об этом.

У каждой СУБД есть свой собственный способ проверки метаданных, подобных этой, но information_schemaна самом деле это ANSI, и я думаю, что Oracle и, по-видимому, SQLite - единственные, которые не поддерживают его каким-либо образом.


3
Использование sqlite: ошибка SQL: такой таблицы нет: INFORMATION_SCHEMA.VIEWS

@lutz: +1, из-за отсутствия поддержки SQLite.
Аликс Аксель,

18
if exists (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[MyTable]') )

Для Microsoft SQL Server я считаю это наиболее полезным, потому что IF EXISTS часто используется при создании сценариев управления схемой. В сценарии у вас, вероятно, уже есть CREATE ViEW [dbo]. [MyView] и приведенный выше простейший фрагмент для копирования и вставки.
Джимми Боссе

15

Для людей, проверяющих существование, Viewиспользуйте это

Из SQL Server 2016 CTP3вы можете использовать новые операторы DIE вместо больших IFоберток

синтаксис

DROP VIEW [IF EXISTS] [schema_name. ] view_name [..., n] [; ]

Запрос:

DROP VIEW IF EXISTS view_name

Больше информации здесь


1

если это Oracle, вы должны использовать таблицу all_views.

Это действительно зависит от ваших dbms.


1

Если вы хотите проверить достоверность и согласованность всех существующих представлений, вы можете использовать следующий запрос

declare @viewName sysname
declare @cmd sysname
DECLARE check_cursor CURSOR FOR 
SELECT cast('['+SCHEMA_NAME(schema_id)+'].['+name+']' as sysname) AS viewname
FROM sys.views

OPEN check_cursor
FETCH NEXT FROM check_cursor 
INTO @viewName

WHILE @@FETCH_STATUS = 0
BEGIN

set @cmd='select * from '+@viewName
begin try
exec (@cmd)
end try
begin catch
print 'Error: The view '+@viewName+' is corrupted .'
end catch
FETCH NEXT FROM check_cursor 
INTO @viewName
END 
CLOSE check_cursor;
DEALLOCATE check_cursor;

1

В SQL Server,

declare @ViewName nvarchar(20)='ViewNameExample'

if exists(SELECT 1 from sys.objects where object_Id=object_Id(@ViewName) and Type_Desc='VIEW')
begin
    -- Your SQL Code goes here ...

end

1

Проверить доступность просмотра можно разными способами

ДЛЯ SQL СЕРВЕРА

использовать sys.objects

IF EXISTS(
   SELECT 1
   FROM   sys.objects
   WHERE  OBJECT_ID = OBJECT_ID('[schemaName].[ViewName]')
          AND Type_Desc = 'VIEW'
)
BEGIN
    PRINT 'View Exists'
END

использовать sysobjects

IF NOT EXISTS (
   SELECT 1
   FROM   sysobjects
   WHERE  NAME = '[schemaName].[ViewName]'
          AND xtype = 'V'
)
BEGIN
    PRINT 'View Exists'
END

использовать sys.views

IF EXISTS (
   SELECT 1
   FROM sys.views
   WHERE OBJECT_ID = OBJECT_ID(N'[schemaName].[ViewName]')
)
BEGIN
    PRINT 'View Exists'
END

используйте INFORMATION_SCHEMA.VIEWS

IF EXISTS (
   SELECT 1
   FROM   INFORMATION_SCHEMA.VIEWS
   WHERE  table_name = 'ViewName'
          AND table_schema = 'schemaName'
)
BEGIN
    PRINT 'View Exists'
END

использовать OBJECT_ID

IF EXISTS(
   SELECT OBJECT_ID('ViewName', 'V')
)
BEGIN
    PRINT 'View Exists'
END

используйте sys.sql_modules

IF EXISTS (
   SELECT 1
   FROM   sys.sql_modules
   WHERE  OBJECT_ID = OBJECT_ID('[schemaName].[ViewName]')
)
BEGIN
   PRINT 'View Exists'
END

0

Чтобы расширить ответ Кевина.

    private bool CustomViewExists(string viewName)
    {
        using (SalesPad.Data.DataConnection dc = yourconnection)
        {
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(String.Format(@"IF EXISTS(select * FROM sys.views where name = '{0}')
                Select 1
            else
                Select 0", viewName));
            cmd.CommandType = CommandType.Text;
            return Convert.ToBoolean(dc.ExecuteScalar(cmd));
        }
    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.