6

我正在使用 VS2010 处理 CLR 存储过程。我需要生成独立部署脚本以在客户服务器上安装此过程。现在我正在使用 Visual Studio,当我按下 F5 并尝试在 DB 服务器上调试 SP 时,它会生成这样的脚本。该脚本放置在bin\Debug\MyStoredProcedure.sql文件中。它看起来像这样:

USE [$(DatabaseName)]

GO
IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id=OBJECT_ID('tempdb..#tmpErrors')) DROP TABLE #tmpErrors
GO
CREATE TABLE #tmpErrors (Error int)
GO
SET XACT_ABORT ON
GO
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRANSACTION
GO
PRINT N'Dropping [dbo].[spMyStoredProcedure]...';


GO
DROP PROCEDURE [dbo].[spMyStoredProcedure];


GO
IF @@ERROR <> 0
   AND @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END

IF @@TRANCOUNT = 0
    BEGIN
        INSERT  INTO #tmpErrors (Error)
        VALUES                 (1);
        BEGIN TRANSACTION;
    END


GO
PRINT N'Dropping [MyStoredProcedure]...';


GO
DROP ASSEMBLY [MyStoredProcedure];


GO
IF @@ERROR <> 0
   AND @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END

IF @@TRANCOUNT = 0
    BEGIN
        INSERT  INTO #tmpErrors (Error)
        VALUES                 (1);
        BEGIN TRANSACTION;
    END


GO
PRINT N'Creating [MyStoredProcedure]...';


GO
CREATE ASSEMBLY [MyStoredProcedure]
    AUTHORIZATION [dbo]
-- here should be long hex string with assembly binary
    FROM 0x4D5A90000300000004000000FFFCD21546869732070726F6772616D...000000000000000000 
    WITH PERMISSION_SET = SAFE;


GO
IF @@ERROR <> 0
   AND @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END

IF @@TRANCOUNT = 0
    BEGIN
        INSERT  INTO #tmpErrors (Error)
        VALUES                 (1);
        BEGIN TRANSACTION;
    END


GO
PRINT N'Creating [dbo].[spMyStoredProcedure]...';


GO
CREATE PROCEDURE [dbo].[spMyStoredProcedure]
@reference UNIQUEIDENTIFIER, @results INT OUTPUT, @errormessage NVARCHAR (4000) OUTPUT
AS EXTERNAL NAME [MyStoredProcedure].[MyCompany.MyProduct.MyStoredProcedureClass].[MyStoredProcedureMethod]


GO
IF @@ERROR <> 0
   AND @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END

IF @@TRANCOUNT = 0
    BEGIN
        INSERT  INTO #tmpErrors (Error)
        VALUES                 (1);
        BEGIN TRANSACTION;
    END


GO
IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION
GO
IF @@TRANCOUNT>0 BEGIN
PRINT N'The transacted portion of the database update succeeded.'
COMMIT TRANSACTION
END
ELSE PRINT N'The transacted portion of the database update failed.'
GO
DROP TABLE #tmpErrors
GO

我想知道,是否可以在没有 Visual Studio 的情况下生成这样的脚本?例如,如果我使用 MSBuild 构建解决方案,然后使用某些工具生成此脚本怎么办?我相信,如果我将程序集读取为字节数组,然后将其序列化为十六进制字符串并插入脚本模板 - 它可以工作,但也许有一些更简单的标准解决方案?

谢谢。

4

5 回答 5

5

或者,假设您将程序集直接从 Visual Studio 部署到某个测试 SQL 服务器;通过右键单击 SSMS(管理工作室)中的程序集创建一个独立的部署脚本并选择:

脚本程序集为 -> 创建到...

这将在 SQL 脚本中为您写入代表 DLL 的十六进制字符串,您可以将其用于单个文件部署。

于 2012-04-23T20:16:07.853 回答
4

好吧,似乎唯一的方法是将程序集作为二进制文件读取,然后使用上面的模板生成脚本。像这样的东西:

            using (var str = File.OpenRead(pathToAssembly))
            {
                int count = 0;
                do
                {
                    var buffer = new byte[1024];
                    count = str.Read(buffer, 0, 1024);

                    for (int i = 0; i < count; i++)
                    {
                        hexStringBuilder.Append((buffer[i] >> 4).ToString("X"));
                        hexStringBuilder.Append((buffer[i] & 0xF).ToString("X"));
                    }
                } while (count > 0);
            }
            // generate script using template from initial question

我已经检查过这种方法并且它有效。

于 2011-01-19T20:27:53.037 回答
1

您所描述的应该可以正常工作,但正如部署 CLR 数据库对象所描述的那样,仅引用已编译的 Dll 似乎更容易。

使用 Transact-SQL 部署程序集

使用 .NET Framework 附带的命令行编译器从源文件编译程序集。

对于 Microsoft Visual C# 源文件:

csc /目标:库 C:\helloworld.cs

对于 Microsoft Visual Basic 源文件:

vbc /目标:库 C:\helloworld.vb

这些命令使用 /target 选项启动 Visual C# 或 Visual Basic 编译器以指定构建库 DLL。

在将程序集部署到测试服务器之前解决所有构建错误和警告。

在测试服务器上打开 SQL Server Management Studio。创建一个新查询,连接到合适的测试数据库(例如 AdventureWorks2008R2)。

通过将以下 Transact-SQL 添加到查询中,在服务器中创建程序集。

使用 PERMISSION_SET = SAFE 从 'c:\helloworld.dll' 创建组件 HelloWorld

然后必须在 SQL Server 实例中创建过程、函数、聚合、用户定义类型或触发器。如果 HelloWorld 程序集在 Procedures 类中包含一个名为 HelloWorld 的方法,则可以将以下 Transact-SQL 添加到查询中,以在 SQL Server 中创建一个名为 hello 的过程。

创建过程你好

作为

外部名称 HelloWorld.Procedures.HelloWorld

于 2011-01-19T17:32:20.487 回答
1

阅读这篇文章,而不是使用/Action:Publish使用/Action:Script /OutputPath:D:\deploymentScript.sql

于 2016-12-21T18:36:03.497 回答
0

您可以从 sys.assembly_files 获取程序集二进制文件。也许你可以用它做点什么。

select *
from sys.assembly_files
于 2011-01-19T18:27:25.607 回答