SQL создать базу данных, если она не существует, непредвиденное поведение

У меня есть длинная хранимая процедура, которая начинается со следующего утверждения:

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, он отлично работает, что заставляет меня думать, что это может быть проблема, связанная с правами.

Ответ 1

Попробуйте использовать

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

Если это не работает, это могут быть разрешения. Это объясняет, почему вы не получаете сообщение об ошибке.

... минимальные разрешения, необходимые для просмотра соответствующей строки, - это разрешение на уровне сервера ALTER ANY DATABASE или VIEW ANY DATABASE, либо разрешение CREATE DATABASE в базе данных master. Базу данных, к которой подключен вызывающий, всегда можно просмотреть в sys.databases

(Из базы данных sys.d в документации MS)

Какие разрешения имеет пользователь, под которым вы работаете?

Попробуйте изменить свой код так, чтобы он просто возвращал содержимое sys.databases, чтобы вы могли его видеть.

Ответ 2

Включение, потому что у меня была похожая проблема: я хотел создать базу данных, если она не существует, а затем выполнить операции с этой базой данных.

Я думаю, что проблема заключалась в том, что скрипт пытался запустить в одном пакете, поэтому он пытался USE базу данных до того, как сервер SQL получил команду CREATE. Это привело к тому, что весь скрипт был полностью изменен, и казалось, что корень проблемы в том, что база данных никогда не создавалась.

В моем случае решением было добавить команду GO после начальной части скрипта, в которой создается таблица, но до того, как я начал работать с ней (например, создание таблиц).

Ответ 3

При сравнении строк используйте LIKE

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