Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何将SQL CLR存储过程部署到多台服务器_Sql Server_Deployment_Sqlclr - Fatal编程技术网

Sql server 如何将SQL CLR存储过程部署到多台服务器

Sql server 如何将SQL CLR存储过程部署到多台服务器,sql-server,deployment,sqlclr,Sql Server,Deployment,Sqlclr,我继承了一个SQLCLR项目,作为我为客户机开发的代码维护项目的一部分。无可否认,我对SQLCLR还很陌生,所以我正试图弄清楚它是如何工作的 我注意到数据库连接字符串存储在项目的属性中,因此我知道在需要时如何更改它。但我有一个问题:是否可以设置多个连接字符串以部署到多个SQL Server实例?在我的例子中,我有一台本地开发人员机器、一台临时服务器和一台生产服务器(每台服务器上都有一个目标数据库的单独副本)。我希望能够将SQL CLR程序集部署到所有3个程序集,而无需更改连接字符串并重新构建每个

我继承了一个SQLCLR项目,作为我为客户机开发的代码维护项目的一部分。无可否认,我对SQLCLR还很陌生,所以我正试图弄清楚它是如何工作的

我注意到数据库连接字符串存储在项目的属性中,因此我知道在需要时如何更改它。但我有一个问题:是否可以设置多个连接字符串以部署到多个SQL Server实例?在我的例子中,我有一台本地开发人员机器、一台临时服务器和一台生产服务器(每台服务器上都有一个目标数据库的单独副本)。我希望能够将SQL CLR程序集部署到所有3个程序集,而无需更改连接字符串并重新构建每个程序集。

请看这里:我认为如果可能,您应该使用上下文连接。这样您就不必重新配置

如果需要不同的凭据或其他内容,可以查询保存这些设置的设置表。使用上下文连接进行连接,查询设置表以获取登录详细信息,然后使用它们再次连接


另外:连接字符串在属性中,但据我所知,settings.xml没有部署,因此您总是将默认值硬编码到settings类中

除了通过VisualStudio进行开发,您不应该部署到任何地方,因此项目中的连接字符串应该始终指向您的开发环境

在开发服务器中测试代码后,您可以在SSMS中通过右键单击有问题的程序集编写程序集脚本,然后执行“脚本程序集为…”,然后执行“创建到…”,然后执行“新建查询窗口”。这将为您提供应该用于部署到QA、登台和生产的基本脚本

一般格式为:

USE [DBName]
GO

CREATE ASSEMBLY [AssemblyName]
AUTHORIZATION [dbo]
FROM 0x0000...
WITH PERMISSION_SET = SAFE
您实际上不需要将程序集文件传播到其他环境,但如果您想这样做,它不会造成任何伤害

如果您想实现自动化,一旦您拥有了基本脚本,您就可以通过以下方式获取更新的汇编代码(上面提到的0x0000):

编辑: 为了完整起见,正如Jeremy在下面的评论中提到的,上面的信息只描述了程序集本身的部署,而不是用于访问程序集中代码的包装器对象的部署。全面部署过程将:

  • 删除现有包装器对象(存储的过程、函数、触发器、类型和聚合)
  • 放下组件
  • 创建新部件
  • 创建包装器对象

  • 将代码部署到开发服务器时,VisualStudio会在bin/Release文件夹中创建一个.sql文件

    这对部署非常有用,需要进行一些清理

    下面是一个perl脚本,我使用它从VS创建的脚本中获取部署脚本

    <> P>它与我的需求和文件格式紧密相关(我使用VS 2010 SP1、SQL 2008 R2、Perl在CygWin中),认为这是一个例子,它不能自动地为每个人工作。
    use strict;
    use warnings;
    
    use Text::Unidecode 'unidecode'; # http://search.cpan.org/dist/Text-Unidecode/
    
    sub ProcessBlock($)
    {
        my $lines = $_[0];
    
        if ($lines =~ "Deployment script for") { return 0; }
        if ($lines =~ "^SET ") { return 0; }
        if ($lines =~ "^:") { return 0; }
        if ($lines =~ "^USE ") { return 0; }
        if ($lines =~ "^BEGIN TRANSACTION") { return 0; }
        if ($lines =~ "extendedproperty") { return 0; }
        if ($lines =~ "^PRINT ") { return 0; }
        if ($lines =~ "#tmpErrors") { return 0; }
        if ($lines =~ "^IF \@\@TRANCOUNT") { return 0; }
    
        my $drop = $lines;
        if ($drop =~ m/^DROP (FUNCTION|PROCEDURE) ([^ ]+);/m)
        { 
            printf("if OBJECT_ID('$2') IS NOT NULL\n");
        }
        elsif ($drop =~ m/^DROP ASSEMBLY \[([^ ]+)\];/m)
        { 
            printf("IF EXISTS (SELECT 1 FROM sys.assemblies WHERE name = '$1')\n");
        }
    
        printf($lines);
        printf("GO\n");
    
        my $create = $lines;
        if ($create =~ m/^CREATE PROCEDURE (\[[^]]+\])\.(\[[^]]+\])/m)
        {
            printf("GRANT EXECUTE ON $1.$2 TO PUBLIC\nGO\n");
        }
        elsif ($create =~ m/^CREATE FUNCTION (\[[^]]+\])\.(\[[^]]+\]).*RETURNS .* TABLE /ms)
        {
            printf("GRANT SELECT ON $1.$2 TO PUBLIC\nGO\n");
        }
        elsif ($create =~ m/^CREATE FUNCTION (\[[^]]+\])\.(\[[^]]+\])/m)
        {
            printf("GRANT EXECUTE ON $1.$2 TO PUBLIC\nGO\n");
        }
    }
    
    
    
    my $block="";
    
    while (<>)
    {
        my $line = $_;
        $line = unidecode($line);
        if ($line =~ "^GO")
        {
            ProcessBlock($block);
            $block = "";
        }
        else
        {
            $block .= $line;
        }
    }
    
    使用严格;
    使用警告;
    使用Text::Unidecode'Unidecode'#http://search.cpan.org/dist/Text-Unidecode/
    子进程块($)
    {
    我的$行=$0];
    if($lines=~“部署脚本”){return 0;}
    如果($lines=~“^SET”){返回0;}
    如果($lines=~“^:”){返回0;}
    如果($lines=~“^USE”){返回0;}
    如果($lines=~“^BEGIN TRANSACTION”){返回0;}
    如果($lines=~“extendedproperty”){return 0;}
    如果($lines=~“^PRINT”){返回0;}
    如果($lines=~“#tmpErrors”){返回0;}
    if($lines=~“^if\@TRANCOUNT”){返回0;}
    我的$drop=$line;
    if($drop=~m/^drop(函数|过程)([^]+);/m)
    { 
    printf(“如果对象_ID('$2')不是空的\n”);
    }
    elsif($drop=~m/^drop ASSEMBLY\[([^]+)\];/m)
    { 
    printf(“如果存在(从sys.assemblies中选择1,其中name='$1')\n”);
    }
    printf(行);
    printf(“GO\n”);
    我的$create=$line;
    如果($create=~m/^create PROCEDURE(\[^]]+\])\(\[[^]]]+\])/m)
    {
    printf(“向公众授予1.2美元的执行权\nGO\n”);
    }
    elsif($create=~m/^create FUNCTION(\[^]]+\])\。(\[^]]+\].*返回值。*表/ms)
    {
    printf(“向公众授予1.2美元的选择权\nGO\n”);
    }
    elsif($create=~m/^create函数(\[^]+\])\(\[^]]+\])/m)
    {
    printf(“向公众授予1.2美元的执行权\nGO\n”);
    }
    }
    我的$block=“”;
    而()
    {
    我的$line=$\ux;
    $line=unidecode($line);
    如果($line=~“^GO”)
    {
    ProcessBlock($block);
    $block=“”;
    }
    其他的
    {
    $block.=$line;
    }
    }
    
    用法:

    perl FixDeploy.pl < YourAssembly.sql > YourAssembly.Deploy.sql
    
    perl-FixDeploy.plyoursassembly.Deploy.sql
    
    这个问题有点模棱两可。您可能希望澄清您是在谈论通过VisualStudio部署SQL CLR代码(我就是这样解释这个问题的),还是代码本身中有一个特定的连接字符串需要调整(GJVDAMP就是这样解释的)。谢谢。运行此脚本并在SSMS中添加程序集后,您很可能需要编写使用CLR程序集的标量值和etc函数的脚本。@JeremyThompson,非常正确,谢谢您提到这一点。我已经更新了我的答案,不再只关注程序集。这不是一个很好的答案,因为您可以轻松地为DB project设置多个部署选项,它只是.NET项目拒绝允许多个配置。但这是一个很好的答案,谢谢微软:(
    perl FixDeploy.pl < YourAssembly.sql > YourAssembly.Deploy.sql