【问题标题】:SQL create database if not exists, unexpected behaviourSQL 创建数据库,如果不存在,意外行为
【发布时间】:2017-04-11 19:54:22
【问题描述】:

我有一个以以下语句开头的长存储过程:

IF  NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'DBNAME')
    BEGIN
        CREATE DATABASE [DBNAME]
    END;

如果我的本地服务器上不存在数据库,则应该在它上创建它。问题是几乎所有时间它都通过存储过程的这一部分而不创建它,这会干扰来自同一过程的其他代码。另一方面,在极少数情况下,它会创建数据库。我的问题是:有没有更好的方法来检查数据库是否存在,因为我已经尝试了至少 10 个。

我尝试过的其他方法:

IF  NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = N'DBNAME')
    BEGIN
        CREATE DATABASE [DBNAME]
    END;

IF  NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'DBNAME')
        BEGIN
            CREATE DATABASE [DBNAME]
        END;

IF  NOT EXISTS (SELECT name FROM master.dbo.sys.databases WHERE name = N'DBNAME')
            BEGIN
                CREATE DATABASE [DBNAME]
        END;

但如果我在我的 sp 之外运行它,它会完美运行,这让我认为它可能是与权限相关的一些问题。

【问题讨论】:

  • IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'DBNAME') 已经在 2014 年工作并显示正确的结果。你有什么错误吗?
  • 你有没有使用任何回滚作为你的过程的一部分。如果是,那么检查它没有被回滚..
  • 不,当我尝试在存储过程中使用它时,我只是得到数据库'DBNAME'不存在。我没有使用交易。
  • 如果您使用的是Transaction,请确保您使用commit
  • MSDN Documentation 应该有帮助!

标签: sql sql-server database sql-server-2014


【解决方案1】:

尝试使用

 If(db_id(N'DBNAME') IS NULL)

如果这不起作用,则可能是权限。这可以解释为什么您没有收到错误消息。

...查看相应行所需的最低权限是 ALTER ANY DATABASE 或 VIEW ANY DATABASE 服务器级权限,或 master 数据库中的 CREATE DATABASE 权限。数据库到 在 sys.databases 中始终可以查看调用者连接的对象

(来自sys.databases on MS documentation

你运行的用户有什么权限?

尝试更改您的代码以仅返回 sys.databases 的内容,以便您可以看到它。

【讨论】:

  • 我得到了同样的结果。
  • 更改了答案以添加有关权限的 cmets。试试看
  • 这正是我提出这个问题的原因。 @StefanL19 如果这是正确答案,请将其标记为正确答案。
【解决方案2】:

比较字符串时使用 LIKE

if (SELECT count(name) FROM sys.databases WHERE name LIKE '%DBNAME%') = 0 

【讨论】:

  • 对于特定情况,没有区别。
  • 这其实是很不正确的;在按名称搜索数据库时,您应该使用LIKE。如果你有一个 exact 名称,OP 有,你应该使用相等评估,not LIKE 比较运算符。此外,正如@StefanL19 所指出的,只要 OP 在查询中正确键入了他的数据库名称,此查询仍然不会返回任何结果。使用 LIKE 和周围的 %s 不会有任何区别,因为立即相等的结果必然包含在查询返回的行集中。
  • 总的来说,这是一个糟糕的提示。我宁愿推荐相反的方法;避免使用 LIKE 除非你有充分的理由使用它(即模糊搜索)
【解决方案3】:

插话是因为我遇到了类似的问题:如果数据库不存在,我想创建一个数据库,然后对该数据库执行操作。

我认为问题在于脚本试图在一批中运行,因此它在 SQL 服务器收到CREATE 命令之前尝试USE 数据库。 这导致整个脚本被还原,问题的根源似乎是数据库从未被创建。

在我的情况下,解决方案是在创建表的脚本的初始部分之后但在我开始使用它之前(例如创建表)之前add a GO command

【讨论】:

    【解决方案4】:

    问题似乎是缺少“GO”来终止语句。这不起作用...

    IF NOT EXISTS(SELECT 1 FROM sys.databases WHERE name='dba')
        CREATE DATABASE [dba]
    
    USE [dba]
    

    但是,这确实...

    IF NOT EXISTS(SELECT 1 FROM sys.databases WHERE name='dba')
        CREATE DATABASE [dba]
    GO
    USE [dba]
    

    特洛伊。 #

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 2017-06-04
      相关资源
      最近更新 更多