Подтвердить что ты не робот

Проект Visual Studio Database: проверка наличия входа в SQL Server до его создания

Когда я создаю проект базы данных Visual Studio для SQL 2012 и синхронизирую его с существующей базой данных (с помощью Compare Schema), я также синхронизую вход в SQL-сервер. Visual Studio генерирует следующие script для входа:

CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass'

Когда я пытаюсь опубликовать сгенерированный SQL на сервере, где этот логин существует, sqlcmd показывает мне ошибку:

The server principal my_user already exists.

Когда я смотрю на sql script, сгенерированный Visual Studio, я вижу, что многие объекты обернуты в операторы IF EXISTS, но CREATE LOGIN не завернуты!

Я попытался связать его вручную в SQL script в проекте, но затем проект не строится и появляется ошибка, указывающая на IF:

SQL70001: This statement is not recognized in this context.

Теперь, как заставить Visual Studio генерировать создание входа script с проверкой IF EXISTS, а также не потерять возможности синхронизации?

4b9b3361

Ответ 1

Измените свойство Build Action файла script (*.sql) на None. Это решает проблему.

Доступно свойство action для сборки, щелкнув правой кнопкой мыши файл sql в проводнике решений, а затем щелкнув свойства. Кроме того, выделите файл в проводнике решений и нажмите "F4".

Ответ 2

Для всех, кто ищет ответ полный, вот что я сделал:

  • В Visual Studio щелкните правой кнопкой мыши свой логин script или, в моем случае, связанный сервер script.
  • Нажмите Свойства.
  • В разделе Advanced → Build Action измените его с Build на None.
  • В PreDeployment script добавьте строку для запуска script. Для меня я переместил связанный сервер script в ту же папку, что и PreDeployment script. Тогда я могу просто сделать

    :r .\linkedserver.sql

  • При развертывании decpac ваш логин script или связанный сервер script будет выполнен успешно.

Ответ 3

Не уверен, правильно ли я понял вопрос, но я пришел сюда из-за подобного сценария. Потеряв несколько часов с "if" и "try catch", вот мой ответ:

Глядя на DacPac исключает пользователей и логинов при экспорте или импорте. Я обнаружил, что должна быть опция исключить логины. Я обнаружил, что вы можете изменить параметры публикации для проекта базы данных, но эти параметры сохраняются в файле *.user, который я обычно не помещаю в исходный элемент управления. В дальнейшем я нашел параметры командной строки для sqlpackage.exe https://blogs.msdn.microsoft.com/ssdt/2015/02/23/new-advanced-publish-options-to-specify-object-types-to-exclude-or-not-drop/. Это, похоже, работает довольно хорошо, также учитывая, что вы можете получить sqlpackage.exe из NuGet (см. https://blogs.msdn.microsoft.com/ssdt/2016/08/22/releasing-ssdt-with-visual-studio-15-preview-4-and-introducing-ssdt-msbuild-nuget-package/). Таким образом, нет никакой возможности построить на машине CI и развернуть результат на сервере.

Edit: Это на VS2015 с соответствующим SSDT.

Ответ 4

У меня точно такая же проблема, и решение от меня состояло в том, чтобы удалить pre-deployment script пользователей:

IF EXISTS(SELECT TOP 1 1 FROM master.sys.server_principals WHERE name = 'my_user') BEGIN
   DROP LOGIN [my_user]
END

Проблема заключается в том, что, возможно, вы изменили пароль, разрешения или настройки LOGIN [my_user] с момента его создания, а после его создания и создания, вы потеряете эти настроенные параметры.

Ответ 5

IF NOT EXISTS
(
SELECT [Column Name Where Username Is Stored] 
FROM [Table Name That Holds The Login's] 
WHERE name = 'my_user'
)
BEGIN 
CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass'

ELSE....

И затем вы можете написать оператор else для его обработки, но хотите ли вы обновлять пароль для нового или просто возвращать сообщение о том, что пользователь уже существует. Дайте мне знать, если вам нужна помощь в написании этой части.