Как создать сценарий установки хранимой процедуры SQL CLR без Visual Studio - PullRequest
5 голосов
/ 19 января 2011

Я работаю над хранимой процедурой CLR, используя VS2010. Мне нужно создать автономный сценарий развертывания, чтобы установить эту процедуру на серверах клиентов. Сейчас я использую 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, а затем сгенерирую этот скрипт с помощью какого-нибудь инструмента? Я считаю, что если я прочитал сборку как байтовый массив, а затем сериализовал ее в шестнадцатеричную строку и вставил в шаблон скрипта - это могло бы сработать, но, может быть, есть более простое стандартное решение?

Спасибо.

Ответы [ 5 ]

4 голосов
/ 24 апреля 2012

Альтернативно, при условии, что вы развернули сборку непосредственно из Visual Studio на каком-нибудь тестовом сервере SQL;создайте автономный сценарий развертывания, щелкнув правой кнопкой мыши сборку в SSMS (Management Studio) и выберите:

Сценарий сборки как -> Создать в ...

Это будет писатьшестнадцатеричная строка, представляющая для вас DLL в сценарии SQL, который вы можете использовать для развертывания одного файла.

4 голосов
/ 19 января 2011

Что ж, похоже, что единственный способ - это прочитать сборку как двоичный файл, а затем сгенерировать скрипт, используя шаблон выше. Примерно так:

            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

Я проверил этот подход, и он работает.

1 голос
/ 21 декабря 2016

Чтение этой записи и вместо использования / Действие: публикация использование / Действие: Script /OutputPath:D:\deploymentScript.sql

1 голос
/ 19 января 2011

То, что вы описали, должно работать нормально, но, как описывает Развертывание объектов базы данных CLR , кажется, проще ссылаться на скомпилированную Dll.

Для развертывания сборки с помощью Transact-SQL

Скомпилируйте сборку из исходного кода файл с использованием компиляторов командной строки входит в .NET Framework.

Для исходных файлов Microsoft Visual C #:

csc / target: библиотека 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 = SAFE

Порядок, функция, агрегат, пользовательский тип или триггер должен затем будет создан в экземпляре SQL Сервер. Если сборка HelloWorld содержит метод с именем HelloWorld в Процедуры класса, следующие Transact-SQL может быть добавлен к запросу создать процедуру под названием привет в SQL Server.

CREATE PROCEDURE привет

AS

ВНЕШНЕЕ ИМЯ HelloWorld.Procedures.HelloWorld

0 голосов
/ 19 января 2011

Вы можете получить двоичный файл сборки из файла sys.assembly_files. Возможно, вы можете сделать что-то с этим.

select *
from sys.assembly_files
...