如何在不使用 Visual Studio 的情况下生成 SQL CLR 存储过程安装脚本
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
或者,假设您已将程序集直接从 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:
This will write the hex string representing the DLL for you in an SQL script you can use for a single file deployment.
好吧,似乎唯一的方法是将程序集作为二进制文件读取,然后使用上面的模板生成脚本。类似的事情:
我已经检查过这种方法并且它有效。
Well, it seems that the only way is to read assembly as binary file and then generate script using template above. Something like that:
I've checked this approach and it works.
您所描述的内容应该可以正常工作,但正如 部署 CLR 数据库对象 所描述的那样仅仅引用编译后的 Dll 似乎更容易。
What you've described should work fine but as Deploying CLR Database Objects describes it seems easier to just to reference the compiled Dll.
阅读 这篇帖子,而不是使用/Action:Publish使用/Action:Script /OutputPath:D:\deploymentScript.sql
Read this post and instead of use /Action:Publish use /Action:Script /OutputPath:D:\deploymentScript.sql
您可以从 sys. assembly_files 获取程序集二进制文件。也许你可以用它做点什么。
You can get the assembly binary from sys.assembly_files. Perhaps you can do something with that.