14

当我为 SQL 2012 创建一个 Visual Studio 数据库项目并将其与现有数据库同步(使用比较架构)时,我还同步了一个 SQL 服务器登录。Visual Studio 为登录生成以下脚本:

CREATE LOGIN [my_user] WITH PASSWORD = 'somesecurepass'

当我尝试在存在此登录名的服务器上发布生成的 SQL 时,sqlcmd 向我显示错误:

The server principal my_user already exists.

当我查看Visual Studio生成的sql脚本时,我看到很多对象被包裹在IF EXISTS语句中,但是CREATE LOGIN没有被包裹!

我试图在项目中的SQL脚本中手动包装它,但是随后项目没有构建并且指向IF的错误:

SQL70001: This statement is not recognized in this context.

现在,我如何强制 Visual Studio 使用 IF EXISTS 检查生成登录创建脚本并且不丢失同步功能?

4

5 回答 5

22

将脚本文件 (*.sql) 的 Build Action 属性更改为 None。这解决了问题。

通过右键单击解决方案资源管理器中的 sql 文件,然后单击属性来访问构建操作属性。或者,在解决方案资源管理器中突出显示该文件,然后按“F4”。

于 2013-04-08T18:45:17.253 回答
5

对于其他正在寻找完整答案的人,这是我所做的:

  1. 在 Visual Studio 中,右键单击您的登录脚本,或者在我的情况下是链接服务器脚本。
  2. 单击属性
  3. 在 Advanced -> Build Action下,将其从 Build 更改为None
  4. 在您的PreDeployment脚本中,添加一行来运行此脚本。对我来说,我将链接服务器脚本移动到与 PreDeployment 脚本相同的文件夹中。然后我可以做

    :r .\linkedserver.sql

  5. 当您部署 decpac 时,您的登录脚本或链接服务器脚本将成功执行。
于 2017-02-07T22:09:01.640 回答
1

不确定我是否正确理解了这个问题,但我来到这里是因为类似的情况。在用“if”和“try catch”浪费了几个小时之后,我的回答是:

查看DacPac exclude users and logins on export 或 import我发现应该有一个选项来排除登录名。我发现您可以更改数据库项目的发布设置,但这些设置存储在 *.user 文件中,我通常不会将其放入源代码管理中。进一步看,我发现了 sqlpackage.exe 的命令行选项 https://blogs.msdn.microsoft.com/ssdt/2015/02/23/new-advanced-publish-options-to-specify-object-types-to-排除或不丢弃/。这似乎工作得很好,还因为您可以从 NuGet 获取 sqlpackage.exe(请参阅https://blogs.msdn.microsoft.com/ssdt/2016/08/22/releasing-ssdt-with-visual-studio- 15-preview-4-and-introducing-ssdt-msbuild-nuget-package/)。因此,没有任何方法可以在 CI 机器上构建并将结果部署到服务器。

编辑:这是在带有相应 SSDT 的 VS2015 上。

于 2016-12-21T09:03:41.433 回答
0

我有完全相同的问题,我的解决方案是使用预部署脚本删除用户:

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

问题是您可能在创建后更改了密码、权限或设置,LOGIN [my_user]在删除并创建后,您将丢失自定义设置。

于 2013-04-05T08:31:28.657 回答
-1
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 语句来处理它,但是您可以将密码更新为新密码,或者只是返回一条消息,说明用户已经存在。让我知道您是否需要帮助编写该部分。

于 2012-06-04T22:04:19.047 回答