【问题标题】:Deploy Visual Studio Database Project Objects to Schema other than "dbo"将 Visual Studio 数据库项目对象部署到“dbo”以外的架构
【发布时间】:2019-10-15 14:05:59
【问题描述】:

我有以下场景。

我在 Visual Studio 数据库项目中有一个 SQLCLR 存储过程。这不应该在dbo 模式中,而是在foo 中。正如我所见,使用 Visual Studio 发布功能时,不可能为 SQLCLR 存储过程提供不同的架构。

所以我必须把它包起来。现在我有两个脚本。

一个添加程序集:

CREATE ASSEMBLY [MyAssembly]
FROM 'MyAssembly.dll';
GO

另一个将存储过程添加到数据库中:

CREATE PROCEDURE [foo].[MyProc](@param NVARCHAR(10))
    AS EXTERNAL NAME MyAssembly.ClassName.MyProc
GO

但现在由于对MyAssembly 的未解决引用而出现错误。我认为这是因为所有(SQLCLR proc、T-SQL wrapper proc、程序集添加脚本)都在同一个项目中,并且是对自身的引用。

在我自己的数据库架构下部署 SQLCLR 存储过程的最佳方式可能是什么?如果可以将其直接添加到 SQLCLR 实现中,那就太好了。

提前致谢。

【问题讨论】:

    标签: sql-server tsql deployment sql-server-data-tools sqlclr


    【解决方案1】:

    实际上,这应该不是问题。从 Visual Studio 2012 开始,可以选择为 T-SQL 包装器对象设置架构。在项目属性中,转到“项目设置”选项卡,在右侧的“常规”部分下,有一个标记为“默认模式”的文本字段。那是用于 T-SQL 包装器对象的架构(我通常不使用 SSDT 部署,所以我只是在 Visual Studio 2015 中重新确认了此信息 — 我知道,我知道,我真的需要更新)。

    我的回答中也提到了这一点:Schema for CLR Stored Procedure During Deployment

    如果您使用的 Visual Studio / SSDT 版本没有设置架构的选项如果您需要将对象放入多个架构中,那么您应该能够简单地添加一个 T-SQL 部署后脚本,将对象移动到所需的架构。通过添加 T-SQL 脚本并将属性设置为“部署后”(或类似的东西),它将被插入到生成的发布脚本的末尾。

    如果只是少数对象不会真正引入新对象,则可以为每个对象做显式声明:

    ALTER SCHEMA [foo] TRANSFER [dbo].[MyProc];
    

    如果是大量对象和/或偶尔会添加新对象,并且您不想记住将它们添加到此部署后包含脚本中,您可以循环浏览已添加的对象列表与该程序集关联以创建一个动态 SQL 脚本,该脚本可以移动它们,而无需对程序集名称进行硬编码(从技术上讲,它甚至可以使用 MSBuild / SSDT 变量动态化):

    DECLARE @SQL NVARCHAR(MAX) = N'';
    
    SELECT @SQL += N'ALTER SCHEMA [foo] TRANSFER [dbo].'
                   + QUOTENAME(obj.[name]) + N';' + NCHAR(0x0D) + NCHAR(0x0A)
    FROM   sys.assembly_modules amd
    INNER JOIN sys.assemblies asm
            ON asm.[assembly_id] = amd.[assembly_id]
    INNER JOIN sys.objects obj
            ON obj.[object_id] = amd.[object_id]
    WHERE  asm.[name] = N'Company.Area.Technology.ProjectName' -- do not use [ and ] here
    AND    SCHEMA_NAME(obj.[schema_id]) = N'dbo'
    
    PRINT @SQL; -- DEBUG (else, comment out)
    
    EXEC (@SQL);
    

    【讨论】:

    • 这可能是更优雅的解决方案。我的解决方案有一个问题,该过程现在在数据库中出现两次,一次使用dbo,另一次使用foo。感谢您的意见。
    • @mburm 谢谢。我刚刚更新了动态脚本:-)
    • @mburm 请在此处查看我最近的更新:如果您使用的是 Visual Studio 2012 或更高版本,则根本不需要此更新。他们添加了用于设置架构名称的发布配置文件选项。
    • 我已经找到了这个选项和一些也暗示他们的帖子。但我认为这对我没有帮助。我不仅有一个模式。目前有三个,可能还会有更多。如果我对这个默认架构理解正确,我可以将其设置为一个。
    • @mburm 正确,该选项适用于所有 T-SQL 包装器对象。因此,您可以将其用于获取最多对象的模式,然后将带有ALTER SCHEMA 的部署后脚本用于其他两个模式。我刚刚更新以澄清这种特殊情况。
    【解决方案2】:

    我可以自己解决。只是一个非常愚蠢的错误......

    我的程序集的名称具有Company.Area.Technology.ProjectName 模式。如果我尝试使用此创建存储过程,则会发生错误,即预期为点。

    CREATE PROCEDURE [foo].[MyProc](@param NVARCHAR(10))
        AS EXTERNAL NAME Company.Area.Technology.ProjectName.ClassName.MyProc
    GO
    

    解决方法是将程序集名称设置在[]之间。

    CREATE PROCEDURE [foo].[MyProc](@param NVARCHAR(10))
        AS EXTERNAL NAME [Company.Area.Technology.ProjectName].ClassName.MyProc
    GO
    

    这行得通。所以我可以将 CLR 过程包装到我自己的 Schema 中。

    【讨论】:

    • 问题:现在该函数在数据库中包含两次,分别在dbofoo
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2011-08-04
    相关资源
    最近更新 更多