2011-03-17 79 views
4

我繼承了一個SQL CLR項目,作爲我正在爲客戶端開發的代碼維護項目的一部分。誠然,我對SQL CLR很陌生,所以我試圖弄清楚它是如何工作的。如何將SQL CLR存儲過程部署到多個服務器

我注意到,數據庫連接字符串存儲在該項目的屬性,所以我知道如何去改變它,如果我需要。我遇到的一個問題是:是否可以設置多個連接字符串以部署到多個SQL Server實例?在我的情況下,我有一臺本地開發機器,一臺登臺服務器和一臺生產服務器(每臺服務器上都有一個單獨的目標數據庫副本)。我希望能夠將SQL CLR程序集部署到全部3,而無需更改連接字符串併爲每個字符串重新構建。

+0

的問題是有點含糊不清。您可能想澄清,如果您正在討論通過Visual Studio部署SQL CLR代碼(我如何解釋問題),或者代碼中是否存在需要調整的特定連接字符串(這是gjvdkamp如何解釋它) 。謝謝。 – 2011-03-17 17:09:43

回答

6

你不應該部署到通過Visual Studio的地方,但發展,因此在項目連接字符串應始終指向你的開發環境。

一旦你的代碼在開發服務器測試,可以編寫腳本,大會在大會討論通過SSMS中右鍵單擊,然後做「腳本大會爲...」,然後「創建爲......」然後「新查詢窗口」。這將爲您提供應該用於部署到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在下面的評論中提到的那樣,上面的信息只描述了Assembly本身的部署,而不是包裝程序對象來訪問Assembly中的代碼。全面部署過程將:

  1. 刪除現有的包裝對象(存儲的特效,函數,觸發器,類型和聚合)
  2. 降大會
  3. 創建新的議會
  4. 創建包裝對象
+0

一旦你運行了這個腳本並在SSMS中添加了Assembly,你很可能需要編寫Scalar-Value等功能來使用CLR程序集。 – 2012-11-13 02:40:57

+0

@JeremyThompson,非常真實,謝謝你的提及。我已經更新了我的答案,不僅僅關注大會。 – 2012-11-15 14:21:25

+0

不是一個很好的答案,因爲tyou可以輕鬆地爲DB項目設置多個部署選項,它只是拒絕允許多個配置的.NET項目。但它是一個很好的答案,我們將得到,謝謝微軟:( – gbjbaanb 2012-11-16 11:42:09

0

看看這裏:The difference between the connections strings in SQLCLR我認爲你應該使用如果可能的情況下連接。這樣你就不必重新配置。

如果您需要不同的憑證或其他憑據,您可以查詢保存這些設置的設置表。使用上下文連接進行連接,查詢設置表以獲取登錄詳細信息,然後再次使用它們進行連接。

另外:連接字符串中的屬性,但據我所知settings.xml中沒有得到部署所以你總是越來越硬編碼到設置類的默認值。

1

當你部署代碼到你的開發服務器,Visual Studio創建在bin/Release文件夾.sql文件。

這可以用於部署,它需要一些清潔。

這是我用來從VS創建的腳本獲取部署腳本的perl腳本。它與我的需求和文件格式密切相關(我使用的是VS 2010 SP1,SQL 2008 R2,cygwin中的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