使用 SQL CLR 的 VS2013 数据库项目 - 对对象 [servername\username](数据库所有者)的未解析引用

VS2013 Database Project using SQL CLR - unresolved reference to object [servername\username] (the Database Owner)

我正在 VS2013 中开发一个包含 C# SQL CLR 存储过程的数据库项目。

程序集所有者是 [servername\User123]
数据库所有者也是 [servername\User123](作为数据库所有者,该用户显然已经存在于服务器上。我通过注释掉 SQL CLR 过程中的代码成功发布了数据库,并且发布,在我取消注释掉该代码后会发生以下情况。)

如果我尝试在 VS 中构建项目,我得到错误:

Error   1   SQL71501: Assembly: [DatabaseProject] has an unresolved reference to object [servername\User123].   

...造成:

CREATE ASSEMBLY [DatabaseProject] AUTHORIZATION [servername\User123]
FROM 0x4D5A90000300000004000000FFFF0000B8000etcetcetcetc
WITH PERMISSION_SET = EXTERNAL_ACCESS
GO

因此,如果在 VS 中,我在 \Security 文件夹中添加一个创建用户脚本:

CREATE USER [servername\User123] FOR LOGIN [servername\User123] WITH DEFAULT_SCHEMA = dbo
GO
GRANT CONNECT TO [servername\User123]

然后我可以构建项目。

但是,如果我随后尝试 发布 数据库,我会收到错误消息:

Creating [servername\User123]...
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 15063, Level 16, State 1, Line 1 The login already has an account under a different user name.
(47,0): SQL72045: Script execution error.  The executed script:
CREATE USER [servername\User123] FOR LOGIN [servername\User123];
An error occurred while the batch was being executed.

有"right"方法吗?

这个问题是由于对SQL服务器如何将数据库"owner"处理为数据库"principal"的简单误解造成的。 "database owner" 的概念以两种不同的方式出现:

  1. 作为数据库级 用户,名称为 dboprincipal_id1。现在,什么服务器级别 Login 映射到这个特定的 User (即 "principal")只是 SID sys.database_principals 中的字段:

    SELECT sdp.*
    FROM   [sys].[database_principals] sdp
    WHERE  sdp.[principal_id] = 1;
    

    此字段将映射到 sys.server_principals 中的 SID 字段:

    SELECT sdp.*, '---' AS [---], ssp.*
    FROM   [sys].[database_principals] sdp
    INNER JOIN [sys].[server_principals] ssp
            ON ssp.[sid] = sdp.[sid]
    WHERE  sdp.[principal_id] = 1;
    

    注意sys.database_principals中的以下字段:

    • 类型
    • type_desc
    • authentication_type
    • 身份验证_type_desc

    鉴于您的数据库当前由 Windows 登录名拥有,运行 上面的查询(第二个查询 - 具有两个表的查询)。接下来,将数据库更改为 sa 拥有。接下来,打开一个新的查询选项卡。最后,运行 在这个新的 window 中使用相同的查询(以便您可以轻松比较 "before" 和 "after" 结果),确保密切关注这 4 个字段上面提到的,以及 sid 字段。 (请注意,可以在没有 Login 的情况下创建 User,显然,这些不会显示在查询 JOINs 到 sys.server_principals,但这个问题专门处理 Logins).

    从所有这些您应该看到,将 Login 指定为数据库的 "owner" 而不是 ,实际上,为 Login 创建一个 User:它只是更新 dbo User[= 的定义72=]。因此,拥有该数据库的 Login 确实 技术上 存在于该数据库中,但始终使用 dbo 的名称而不是其实际名称姓名。这就是您收到以下错误的原因:

    The login already has an account under a different user name.

  2. 作为 数据库角色,数据库中的任何 用户 都可以添加到其中,以便获得这些角色权限。

修复:

  • \Security 文件夹中删除您的 CREATE USER 脚本。
  • 改用AUTHORIZATION [dbo]