如何在不使用 Visual Studio 的情况下生成 SQL CLR 存储过程安装脚本

发布于 2024-10-12 12:22:44 字数 2613 浏览 4 评论 0原文

我正在使用 VS2010 开发 CLR 存储过程。我需要生成独立的部署脚本以在客户服务器上安装此过程。现在我正在使用 Visual Studio,当我按 F5 并尝试在数据库服务器上调试 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 构建解决方案,然后使用某些工具生成此脚本会怎样?我相信,如果我将程序集读取为字节数组,然后将其序列化为十六进制字符串并插入到脚本模板中 - 它可以工作,但也许有一些更简单的标准解决方案?

谢谢。

I am working on CLR stored procedure using VS2010. I need to generate standalone deployment script to install this procedure at customer servers. Now I am using Visual Studio which generate such script when I press F5 and try to debug SP on DB server. This script is placed at bin\Debug\MyStoredProcedure.sql file. It looks like this:

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

I am wondering, is it possible to generate such script without Visual Studio? For example, what if I build solution with MSBuild and then generate this script with some tool? I believe, that if I read assembly as byte array and then serialize it to hex string and insert into script template - it could work, but maybe there is some easier standard solution?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白色秋天 2024-10-19 12:22:44

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

将汇编脚本编写为 ->创建到...

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

Alternately, assuming you have the assembly deployed direct from visual studio to some test SQL server; create a standalone deployment script by right clicking the assembly in SSMS (management studio) and select:

Script assembly as -> Create To...

This will write the hex string representing the DLL for you in an SQL script you can use for a single file deployment.

待天淡蓝洁白时 2024-10-19 12:22:44

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

            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

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

Well, it seems that the only way is to read assembly as binary file and then generate script using template above. Something like that:

            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

I've checked this approach and it works.

反话 2024-10-19 12:22:44

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

使用以下方式部署程序集
Transact-SQLTransact-SQL

从源代码编译程序集
使用命令行编译器的文件
包含在 .NET Framework 中。

对于 Microsoft Visual C# 源文件:

csc /target:library C:\helloworld.cs

对于 Microsoft Visual Basic 源
文件:

vbc /target:库 C:\helloworld.vb

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

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

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

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

从以下位置创建程序集 HelloWorld
'c:\helloworld.dll' 带有
PERMISSION_SET = 安全

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

创建过程你好

AS

外部名称
HelloWorld.Procedures.HelloWorld

What you've described should work fine but as Deploying CLR Database Objects describes it seems easier to just to reference the compiled Dll.

To deploy the assembly using
Transact-SQL

Compile the assembly from the source
file using the command line compilers
included with the .NET Framework.

For Microsoft Visual C# source files:

csc /target:library C:\helloworld.cs

For Microsoft Visual Basic source
files:

vbc /target:library C:\helloworld.vb

These commands launch the Visual C# or
Visual Basic compiler using the
/target option to specify building a
library DLL.

Resolve all build errors and warnings
before deploying the assembly to the
test server.

Open SQL Server Management Studio on
the test server. Create a new query,
connected to a suitable test database
(such as AdventureWorks2008R2).

Create the assembly in the server by
adding the following Transact-SQL to
the query.

CREATE ASSEMBLY HelloWorld from
'c:\helloworld.dll' WITH
PERMISSION_SET = SAFE

The procedure, function, aggregate,
user-defined type, or trigger must
then be created in the instance of SQL
Server. If the HelloWorld assembly
contains a method named HelloWorld in
the Procedures class, the following
Transact-SQL can be added to the query
to create a procedure called hello in
SQL Server.

CREATE PROCEDURE hello

AS

EXTERNAL NAME
HelloWorld.Procedures.HelloWorld

祁梦 2024-10-19 12:22:44

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

Read this post and instead of use /Action:Publish use /Action:Script /OutputPath:D:\deploymentScript.sql

迎风吟唱 2024-10-19 12:22:44

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

select *
from sys.assembly_files

You can get the assembly binary from sys.assembly_files. Perhaps you can do something with that.

select *
from sys.assembly_files
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文