如何检查视图是不是存在,如果不存在则创建

Posted

技术标签:

【中文标题】如何检查视图是不是存在,如果不存在则创建【英文标题】:How to check if a view exists and create if it does not如何检查视图是否存在,如果不存在则创建 【发布时间】:2018-03-07 09:23:58 【问题描述】:

如果 SQL Server 2016 中不存在,我想创建一个视图

IF EXISTS(SELECT 1 FROM sys.views 
     WHERE Name = 'VI_ALL_CITIES_AS_CATEGORY')
BEGIN
CREATE VIEW VI_ALL_CITIES_AS_CATEGORY AS
    SELECT PERSONS.FIRST_NAME AS 'Име', PERSONS.LAST_NAME AS 'Фамилия', CITIES.CITY_NAME AS 'Град'
    FROM CITIES
    LEFT JOIN PERSONS ON CITIES.ID = PERSONS.CITY_ID ;
END

但它给了我错误:

语法错误:'CREATE VIEW' 必须是 批处理。

【问题讨论】:

除非我读错了你的 SQL,否则你的 EXISTS 正在检查是否存在,然后你试图 CREATE 它。如果视图已经存在,CREATE 将失败。 另一种解决方案:set noexec:codereview.stackexchange.com/a/13858/40484 【参考方案1】:

你有两个选择:

1) 如果您使用的是 SSMS 或任何可以将您的脚本分成不同批次的客户端:

IF EXISTS(SELECT 'view exists' FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = N'YourViewName'AND TABLE_SCHEMA = 'YourViewSchema')
BEGIN
    DROP VIEW YourViewSchema.YourViewName
END

GO -- This will make the next statement the first in it's batch

CREATE VIEW YourViewSchema.YourViewName AS
SELECT something = 1
FROM YourTable

GO

2) 如果您不能将代码拆分成批次,您将不得不使用动态 SQL 来“欺骗”引擎来创建您的视图:

 IF NOT EXISTS(SELECT 'view exists' FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = N'YourViewName'AND TABLE_SCHEMA = 'YourViewSchema')
    BEGIN
        DECLARE @v_ViewCreateStatement VARCHAR(MAX) = '
            CREATE VIEW YourViewSchema.YourViewName AS
                SELECT something = 1
                FROM YourTable'

        EXEC (@v_ViewCreateStatement)

    END

请注意,1) 是 IF EXISTS,2) 是 IF NOT EXISTS

这样做的原因是大多数 DDL 语句需要在批处理中放在首位,因此很遗憾,您不能将 CREATE 对象语句放在其他语句之后。

【讨论】:

【参考方案2】:

试试这个方法

IF NOT EXISTS
(
    SELECT 1
    FROM sys.views
    WHERE Name = 'VI_ALL_CITIES_AS_CATEGORY'
)
BEGIN

    EXEC('CREATE VIEW VI_ALL_CITIES_AS_CATEGORY AS SELECT 1 as Val')

END
GO

ALTER VIEW VI_ALL_CITIES_AS_CATEGORY
AS
SELECT 
    PERSONS.FIRST_NAME AS 'Име',
    PERSONS.LAST_NAME AS 'Фамилия',
    CITIES.CITY_NAME AS 'Град'
    FROM CITIES
       LEFT JOIN PERSONS 
          ON CITIES.ID = PERSONS.CITY_ID

【讨论】:

中间有一个 GO 语句,请记住,如果此代码在存储过程中,这将不起作用。【参考方案3】:

如果您不想删除当前视图,可以使用临时名称创建一个新视图,然后使用 IF 重命名,使用仅在一批中执行的 exec sp_rename,如下所示:

CREATE VIEW VI_ALL_CITIES_AS_CATEGORY_TEMP AS
SELECT PERSONS.FIRST_NAME AS 'Име', PERSONS.LAST_NAME AS 'Фамилия', CITIES.CITY_NAME AS 'Град'
FROM CITIES
LEFT JOIN PERSONS ON CITIES.ID = PERSONS.CITY_ID ;

GO

IF OBJECT_ID('dbo.VI_ALL_CITIES_AS_CATEGORY', 'V') IS NULL
exec sp_rename 'dbo.VI_ALL_CITIES_AS_CATEGORY_TEMP', 'VI_ALL_CITIES_AS_CATEGORY'

GO

IF OBJECT_ID('dbo.VI_ALL_CITIES_AS_CATEGORY_TEMP', 'V') IS NOT NULL
drop view VI_ALL_CITIES_AS_CATEGORY_TEMP

【讨论】:

以上是关于如何检查视图是不是存在,如果不存在则创建的主要内容,如果未能解决你的问题,请参考以下文章

jQuery检查Cookie是不是存在,如果不存在则创建它

Shell 脚本检查 dir 目录是不是存在然后更改路径,如果不存在则使用该名称创建 dir 并检查文件名不存在

从 Excel VBA-检查访问表是不是存在/如果不存在,则创建/复制

如何遍历列,检查任何列中是不是存在特定值,改变新列并输入 1 如果存在,如果不存在则输入 0?

如何检查 var 是不是存在于数据库列中,如果不存在则不执行任何操作

“如果不存在则创建表” - 如何也检查架构?