使用可变域用户登录创建用户脚本

Create user script with variable domain user login

我们有一个包含创建用户脚本的 DACPAC。 用户有一个登录需要设置为 windows 域用户 当我们为 Test/Staging/Release 构建时,我们需要能够为用户登录应用不同的域和用户。

我以为我们可以使用 SQLCMD 变量,但我在尝试使用它时遇到了 SQL71501 错误该脚本看起来像这样:

CREATE USER [Username]
    For Login [$(SQLLoginDomain)]
    WITH DEFAULT_SCHEMA = [SCHEMANAME]
GO

基于痛苦的经验,我的建议是将环境特定的任何内容排除在 SQL 服务器数据库项目之外。相反,在部署 DACPAC 之后,将任何特定于环境(许可等)的内容作为单独的 T-SQL 脚本应用。如果您使用 Release Management 执行此操作,我有一个详尽的博客系列,其中包括发布 DACPAC 和单独的权限脚本 here.The post about applying a tokenised permissions script is here

我们最终通过在 dacpac 中使用 post 部署脚本解决了这个问题,只要您在尝试呼叫用户之前进行检查以查看他们是否已经存在,一切都会正常进行,因为这就是只有在预部署脚本之外才能使用它们的地方。

您可以从 sys.dm_exec_sessions 系统视图中读取 Windows 域。

例如,您可以将类似的内容放入 DACPAC 的 post-部署脚本中...

DECLARE @host_name nvarchar(128);
DECLARE @nt_domain nvarchar(128);

SELECT
    @host_name = host_name,
    @nt_domain = nt_domain
FROM
    sys.dm_exec_sessions
WHERE
    session_id = @@SPID;

-- If the domain is present, setup the login/user.
-- Otherwise, we are probably running under test environment, so we can skip this.
-- `@nt_domain = @host_name` tends to hold for LocalDB.

IF @nt_domain IS NOT NULL AND @nt_domain <> @host_name BEGIN

    DECLARE @user_nonquoted nvarchar(128) = @nt_domain + '\YourUserName';
    DECLARE @user nvarchar(128) = QUOTENAME(@user_nonquoted);

    IF @user_nonquoted NOT IN (SELECT name FROM sys.database_principals)
        EXEC ('CREATE LOGIN ' + @user + ' FROM WINDOWS');
    IF @user_nonquoted NOT IN (SELECT name FROM sys.server_principals)
        EXEC ('CREATE USER ' + @user + ' FOR LOGIN ' + @user);

END