這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)SQL Compare怎樣使用SQL比較命令行從源代碼管理中進(jìn)行自定義部署,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:申請(qǐng)域名、網(wǎng)站空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、如皋網(wǎng)站維護(hù)、網(wǎng)站推廣。
SQL Compare是一款比較和同步SQL Server數(shù)據(jù)庫(kù)結(jié)構(gòu)的工具。現(xiàn)有超過150,000的數(shù)據(jù)庫(kù)管理員、開發(fā)人員和測(cè)試人員在使用它。當(dāng)測(cè)試本地?cái)?shù)據(jù)庫(kù),暫存或激活遠(yuǎn)程服務(wù)器的數(shù)據(jù)庫(kù)時(shí),SQL Compare將分配數(shù)據(jù)庫(kù)的過程自動(dòng)化。
Giorgi Abashidze解釋了他的團(tuán)隊(duì)如何使用帶有SQL Compare命令行和一些SQL同義詞的兩階段部署過程來自動(dòng)為其每個(gè)客戶進(jìn)行自定義部署,而只需要在源代碼管理中為每個(gè)版本維護(hù)一個(gè)分支。
在我以前的文章中,從使用SQL比較命令行的源代碼控制到數(shù)據(jù)庫(kù),我解釋了我的團(tuán)隊(duì)如何使用SQL比較命令行為我們的客戶自動(dòng)化數(shù)據(jù)庫(kù)部署,而無需訪問實(shí)際的暫存數(shù)據(jù)庫(kù)或生產(chǎn)數(shù)據(jù)庫(kù),這是不可能的這是一個(gè)銀行數(shù)據(jù)庫(kù)。我展示了如何通過僅訪問我們的開發(fā)數(shù)據(jù)庫(kù)(包含在TFS源代碼管理下),如何使用SQL Compare命令行來部署數(shù)據(jù)庫(kù)元數(shù)據(jù)和所有客戶通用的代碼。
但是,除了此共享代碼外,還必須為我們的每個(gè)客戶提供每個(gè)軟件版本的獨(dú)特變體,以便向他們提供可滿足其不同業(yè)務(wù)和合規(guī)性要求的自定義例程。我們每個(gè)客戶都需要其中一些例程,當(dāng)然,此專有功能應(yīng)始終僅部署到該客戶的生產(chǎn)數(shù)據(jù)庫(kù)中:至關(guān)重要的是,任何客戶都不能看到專門為另一位客戶編寫的邏輯。
我們?nèi)绾螌?shí)現(xiàn)這一目標(biāo)?傳統(tǒng)的觀點(diǎn)似乎是,在每個(gè)發(fā)行版中,我們將數(shù)據(jù)庫(kù)版本的每個(gè)特定于客戶的變體視為一個(gè)單獨(dú)的分支。但是,這可能會(huì)增加構(gòu)建的復(fù)雜性。有了一些創(chuàng)造力,我們可以避免這種情況,而是為每個(gè)新版本創(chuàng)建一個(gè)分支,我們可以使用該分支來維護(hù)和部署我們每個(gè)客戶的所有共享邏輯,以及專用于無限數(shù)量客戶的邏輯。
在本文中,我將說明如何使用SQL Compare命令行,同義詞和一些獨(dú)創(chuàng)性來完成所有這些工作。
我們?nèi)绾螌⒖蛻籼囟ǖ睦檀鎯?chǔ)在單個(gè)數(shù)據(jù)庫(kù)中
因此,為了更接近我們的開發(fā)數(shù)據(jù)庫(kù)的構(gòu)建方式,我們假設(shè)我們的Trunk結(jié)合了我們所有的邏輯。假設(shè)我們有三個(gè)客戶Cust1,Cust2和Cust3。
我們還有一些代碼,即SQL存儲(chǔ)過程,稱為SQL存儲(chǔ)過程loan.calculate_effective_rate,該過程根據(jù)某種算法來計(jì)算在一段時(shí)間內(nèi)對(duì)貸款支付的實(shí)際利率,稱為“有效利率”。對(duì)于所有客戶來說,這是相同的代碼,但是有一天,客戶Cust1要求我們更改其版本的算法,這意味著我們現(xiàn)在需要維護(hù)和部署“有效率”過程的兩個(gè)不同版本。
首先,我們需要effective_rate按照Cust1的要求,為該過程實(shí)現(xiàn)替代算法(從這里開始,我將使用其名稱的這種縮寫形式)。我們只有一個(gè)開發(fā)數(shù)據(jù)庫(kù),稱為Trunk,并且由于任何例程中每個(gè)例程的名稱都必須唯一,這意味著我們必須有一種命名策略來區(qū)分這些變體。
我們這樣做的方法是:
將effective_rate過程重命名為effective_rate_default,為我們的客戶創(chuàng)建默認(rèn)的計(jì)算實(shí)現(xiàn)。
創(chuàng)建一個(gè)名為的新過程effective_rate_cust1。就參數(shù)和參數(shù)類型而言,它應(yīng)具有與舊簽名相同的簽名。這必須僅部署到Cust1組織。
這意味著所有客戶的應(yīng)用程序代碼現(xiàn)在都必須調(diào)用該effective_rate_default過程,但必須調(diào)用的Cust1除外effective_rate_cust1。但是,我們不希望對(duì)任何客戶的調(diào)用代碼進(jìn)行任何更改。畢竟,該程序的目的沒有改變,但是我們現(xiàn)在有多個(gè)實(shí)施同一操作(計(jì)算貸款的有效利率)的方法。相反,我們使用同義詞表示具有多個(gè)實(shí)現(xiàn)的任何動(dòng)作。換句話說,調(diào)用者代碼從不直接調(diào)用確切的實(shí)現(xiàn),而是調(diào)用操作(SQL同義詞)。
因此,在這種情況下,我們將創(chuàng)建一個(gè)SQL同義詞并將其部署到每個(gè)客戶,該SQL同義詞具有effective_rate引用該effective_rate_default過程的名稱。當(dāng)然,Cust1僅此同義詞必須不引用默認(rèn)過程,而是引用Cust1變體。但是,正如我已經(jīng)提到的,我們?cè)谠创a管理中僅維護(hù)一個(gè)數(shù)據(jù)庫(kù),而在Trunk(以及任何發(fā)行分支)中,每個(gè)同義詞始終僅引用相關(guān)操作的默認(rèn)實(shí)現(xiàn)。那么我們?nèi)绾螌?shí)現(xiàn)這一目標(biāo)呢?
答案是一個(gè)兩階段的部署過程。第一階段向每個(gè)客戶部署effective_rate_default過程以及effective_rate引用該過程的同義詞。第二階段僅將過程部署到Cust1 ,然后在Cust1數(shù)據(jù)庫(kù)中刪除同義詞,并創(chuàng)建一個(gè)引用的新過程。
effective_rate_cust1effective_rateeffective_rate_cust1
通過遵循這種方法,基于對(duì)每個(gè)客戶的SQL同義詞和兩階段部署過程,我們可以在一個(gè)開發(fā)數(shù)據(jù)庫(kù)中包含所需的專用例程,因此仍然可以為我們的客戶提供代碼,考慮到不同的業(yè)務(wù)和合規(guī)性要求。
讓我們看看如何使用SQL Compare命令行實(shí)現(xiàn)此兩階段部署過程。
使用SQL比較的2階段部署
我們將在簡(jiǎn)化的部署示例中稍作擴(kuò)展,并假設(shè)有三個(gè)客戶(Cust1,Cust2和Cust3)都需要定制“有效率”算法的變體。
部署過程的第一階段將生成一個(gè)部署腳本,該腳本將交付給每個(gè)客戶數(shù)據(jù)庫(kù)并在每個(gè)客戶數(shù)據(jù)庫(kù)上運(yùn)行。這將使所有通用數(shù)據(jù)庫(kù)例程(即,沒有名稱以客戶別名結(jié)尾的任何例程)升級(jí)到相同版本。
第二階段生成零個(gè)或多個(gè)特定于客戶的同步腳本,這些腳本僅創(chuàng)建或更新特定于該客戶的SQL例程,這意味著任何例程的名稱都以該用戶的別名結(jié)尾,在這種情況下,cust1,cust2或cust3。它還將刪除并重新創(chuàng)建任何同義詞,在本例中為effective_rate同義詞,以便每個(gè)人始終綁定到正確的基礎(chǔ)實(shí)現(xiàn)。
為了滿足這些要求,我們對(duì)所需的每個(gè)同步腳本執(zhí)行一次SQL比較命令行。
階段1:生成常規(guī)部署腳本
在部署過程的第一階段,我們只執(zhí)行一次SQL Compare CL,并通過提供一個(gè)名為“ shared.xml ” 的XML argfile,傳入指示其比較哪些數(shù)據(jù)庫(kù)以及如何進(jìn)行比較的所有參數(shù):
“%programfiles(x86)%\ Red Gate \ SQL Compare 13 \ sqlcompare” /Argfile:"shared.xml“
我在上一篇文章中解釋了此Argfile的基本內(nèi)容,但重要的一點(diǎn)是,首先,它是直接從源代碼控制位置比較數(shù)據(jù)庫(kù)的兩個(gè)即時(shí)點(diǎn)版本,即新版本和先前版本。 ,其次包括對(duì)相應(yīng)過濾器文件(shared.scpf)的引用。此過濾器文件使用如下所示的過濾器表達(dá)式排除任何特定于客戶的模式對(duì)象版本(在這種情況下,任何以Cust1,Cust2或Cust3結(jié)尾的版本):
(@NAME NOT LIKE '%[_]cust1') AND (@NAME NOT LIKE '%[_]cust2') AND (@NAME NOT LIKE '%[_]cust3')
當(dāng)然,如果您的客戶別名全部遵循標(biāo)準(zhǔn)模式(如本簡(jiǎn)化示例中的做法),則可以使用更通用的過濾器,例如(@NAME NOT LIKE' %[_]cust[0-9]')。但是,我們所有的真實(shí)客戶名稱都不相同,因此不可能進(jìn)行這種模式匹配。
結(jié)果,SQL Compare將生成一個(gè)SQL同步腳本,該腳本將僅創(chuàng)建effective_rate_default存儲(chǔ)過程,然后刪除該effective_rate同義詞,然后重新創(chuàng)建該同義詞,以使其引用默認(rèn)過程(CREATE SYNONYM effective_rate FOR effective_rate_default)。
階段2:生成客戶特定的部署腳本
實(shí)際上,對(duì)于每個(gè)客戶,此階段包括兩個(gè)部分:
SQL Compare自動(dòng)生成一個(gè)腳本,該腳本將創(chuàng)建或修改所需的特定于客戶的例程
我們“重置”每個(gè)客戶數(shù)據(jù)庫(kù)中的所有同義詞,以便它們引用正確的基礎(chǔ)實(shí)現(xiàn)(存儲(chǔ)過程或函數(shù)等)。為此,我們將所需的代碼“注入”到每個(gè)自動(dòng)生成的自定義腳本的末尾
我們針對(duì)需要自定義代碼的每個(gè)客戶再次執(zhí)行SQL Compare CL,只需簡(jiǎn)單地每次切換argfile即可指示SQL Compare 僅包含名稱以該客戶的別名結(jié)尾的對(duì)象。我們將所有客戶別名的列表存儲(chǔ)在開發(fā)數(shù)據(jù)庫(kù)中。
“%programfiles(x86)%\ Red Gate \ SQL比較13 \ sqlcompare” /Argfile:"cust1.xml“ “%programfiles(x86)%\ Red Gate \ SQL比較13 \ sqlcompare” /Argfile:"cust2.xml“ “%programfiles(x86)%\ Red Gate \ SQL比較13 \ sqlcompare” /Argfile:"cust3.xml“
每個(gè)argfile的內(nèi)容與shared.xml文件的內(nèi)容幾乎相同,唯一的區(qū)別是每個(gè)特定于客戶的argfile包含對(duì)該客戶的過濾器文件的引用(例如Cust1.scpf),該引用指示SQL Compare CL使用以下表達(dá)式,僅檢測(cè)特定于該客戶的更改
(@NAME LIKE '%[_]cust1')
當(dāng)比較運(yùn)行時(shí)(例如對(duì)于Cust1),SQL Compare將生成一個(gè)部署腳本,該腳本將創(chuàng)建,修改或刪除*_cust1代表Cust1已安裝版本的主干分支中的任何對(duì)象,因此它將與源代碼控制中的最新版本同步。在這種情況下,它將創(chuàng)建effective_rate_cust1存儲(chǔ)過程。
但是,SQL Compare為每個(gè)客戶自動(dòng)生成的部署腳本不會(huì)將當(dāng)前的effective_rate同義詞(通過在階段1中運(yùn)行通用腳本創(chuàng)建)替換為引用effective_rate_cust1存儲(chǔ)過程的同義詞,因?yàn)樵撏x詞在Trunk或任何單個(gè)分支中對(duì)于每個(gè)主要版本(v241,v242等),始終引用默認(rèn)實(shí)現(xiàn)。
因此,每次SQL Compare自動(dòng)生成特定于客戶的同步腳本時(shí),我們都需要對(duì)其進(jìn)行修改,以“重置”腳本中的任何同義詞,以便它引用相關(guān)操作的特定于特定于客戶的實(shí)現(xiàn),或者如果不再需要自定義變體,則恢復(fù)為默認(rèn)操作。
我們不能為此使用標(biāo)準(zhǔn)的SQL Compare部署后腳本,首先,因?yàn)楫?dāng)直接與源代碼控制位置進(jìn)行比較時(shí),該工具當(dāng)前不支持使用它們。無論如何,由于我們簡(jiǎn)單的“每個(gè)發(fā)布一個(gè)分支”策略,我們無法動(dòng)態(tài)地為每個(gè)客戶生成部署后腳本,也無法更改每個(gè)腳本中的同義詞以引用正確的客戶實(shí)現(xiàn)。使其起作用的唯一方法是使用“每個(gè)版本的每個(gè)客戶變體一個(gè)分支”的更復(fù)雜的構(gòu)建方案,將每個(gè)分支腳本化到一個(gè)文件夾中,然后向其中添加一個(gè)后部署腳本,以為此重置同義詞。
但是,我們更喜歡使用更簡(jiǎn)單的源代碼控制方法,那么我們?cè)撛趺醋瞿???dāng)SQL Compare將特定于客戶的同步文件寫入我們選擇的目錄(由該out客戶的XML argfile中的參數(shù)指定)時(shí),我們將使用一個(gè)本地工具將其打開,并在自動(dòng)生成的代碼的末尾添加一行,以執(zhí)行我們編寫的存儲(chǔ)過程稱為switch_synonyms_to_customer。此過程接受組織的別名的參數(shù)(應(yīng)將同義詞綁定到該參數(shù)),然后遍歷所有SQL同義詞,將它們逐個(gè)刪除,然后使用同義詞引用的基礎(chǔ)對(duì)象的適當(dāng)名稱重新創(chuàng)建它們。默認(rèn)值或?qū)S美蹋ㄈ绻囟蛻粜枰?/p>
因此,對(duì)于cust1:
EXEC altasoft.switch_synonyms_to_customer @alias = 'cust1'
對(duì)于cust2:
EXEC altasoft.switch_synonyms_to_customer @alias = 'cust2'
等等…
為每個(gè)客戶運(yùn)行部署
我們向每個(gè)客戶提供用于部署所有公共對(duì)象的常規(guī)部署腳本,并且,如果需要,我們還為每個(gè)客戶提供為其定制邏輯提供的其他自定義部署腳本,該腳本還將正確重置所有同義詞。他們必須始終始終先運(yùn)行常規(guī)腳本,只有完成后才運(yùn)行其自定義腳本。
如果您正在為許多不同的客戶開發(fā)數(shù)據(jù)庫(kù)應(yīng)用程序,那么您的客戶的需求將開始出現(xiàn)分歧,并且單個(gè)部署無法滿足您的需求。畢竟,當(dāng)?shù)氐亩愂蘸头梢约安煌纳虡I(yè)慣例將決定客戶如何計(jì)算某些財(cái)務(wù)價(jià)值。
為了將所需邏輯中的所有變體僅提供給需要它的客戶,SQL Compare命令行可以完成99%的工作。它會(huì)生成一個(gè)通用同步腳本,以部署每個(gè)客戶所需的從發(fā)行到發(fā)行的任何更改,然后針對(duì)具有“特殊”要求的每個(gè)客戶生成單獨(dú)的同步腳本文件。
通過使用同義詞表示每個(gè)必需的業(yè)務(wù)操作,并在每個(gè)特定于客戶的同步腳本的末尾“手動(dòng)”重置它們,以便它們始終引用此操作的正確實(shí)現(xiàn),我們避免了對(duì)調(diào)用者進(jìn)行任何更改碼。
在每個(gè)發(fā)行版中,都有可能為客戶創(chuàng)建了一些新邏輯,或者更新了現(xiàn)有的自定義邏輯或?qū)⑵鋭h除。如果某些操作不再需要自定義實(shí)現(xiàn),則將其刪除,因此客戶將返回該操作的默認(rèn)實(shí)現(xiàn)。
上述就是小編為大家分享的SQL Compare怎樣使用SQL比較命令行從源代碼管理中進(jìn)行自定義部署了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。