我继承了一个SQL CLR项目,作为我正在为客户工作的代码维护项目的一部分。我承认,我对SQL CLR很陌生,所以我想弄清楚它是如何工作的。
我注意到数据库连接字符串存储在项目的属性中,所以如果需要,我知道如何更改它。我遇到的一个问题是:是否可以设置多个连接字符串以部署到多个SQL Server实例?在我的例子中,我有一个本地开发机器,一个登台服务器和一个生产服务器(每个服务器上有一个目标数据库的单独副本)。我希望能够将SQL CLR程序集部署到所有3,而无需更改连接字符串并为每个部分重新构建。
答案 0 :(得分:6)
除了通过Visual Studio进行开发之外,您不应该部署到任何地方,因此Project中的连接字符串应始终指向您的开发环境。
在开发服务器中测试完代码之后,您可以通过右键单击有问题的程序集来编写SSMS中的程序集,并执行“Script Assembly As ...”然后“Create To ...”和然后“新查询窗口”。这将为您提供应用于部署到QA,Staging和Production的基本脚本。
一般格式为:
USE [DBName]
GO
CREATE ASSEMBLY [AssemblyName]
AUTHORIZATION [dbo]
FROM 0x0000...
WITH PERMISSION_SET = SAFE
你真的不需要将程序集文件传播到其他环境,不过如果你想要它不会受到伤害。
如果你想自动化它,一旦你有了这个基本脚本,你总是可以通过以下方式获取更新的汇编代码(上面提到的0x0000):
SELECT Content FROM sys.assembly_files WHERE name = 'AssemblyName'
编辑: 为了完整起见,正如Jeremy在下面的评论中提到的,上述信息仅描述了程序集本身的部署,而不是用于访问程序集内代码的包装器对象。完整的部署过程将:
答案 1 :(得分:1)
将代码部署到开发服务器时,Visual Studio会在bin / Release文件夹中创建.sql文件。
这对部署很有用,需要一些清理。
这是一个perl脚本,用于从VS创建的脚本中获取部署脚本。
它与我的需求和文件格式密切相关(我在cygwin中使用的是VS 2010 SP1,SQL 2008 R2,perl),请将此视为一个示例,它可能无法为所有人自动运行。
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;
}
}
用法:
perl FixDeploy.pl < YourAssembly.sql > YourAssembly.Deploy.sql
答案 2 :(得分:0)
看这里:The difference between the connections strings in SQLCLR我认为你应该尽可能使用上下文连接。这样您就不必重新配置了。
如果您需要不同的凭据或其他内容,则可以查询包含这些设置的设置表。使用上下文连接进行连接,查询设置表以获取登录详细信息,然后再使用它们进行连接。
此外:连接字符串位于属性中,但据我所知,settings.xml未部署,因此您始终将默认值硬编码到设置类中。