翻譯|使用教程|編輯:楊鵬連|2020-07-08 11:01:08.437|閱讀 257 次
概述:本文介紹了所有這些任務(wù),并演示了使用SQL Compare可以實(shí)現(xiàn)的功能。在隨后的文章中,我將顯示任務(wù)槽到自動(dòng)SQL Change Automation過程中。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
SQL Compare是一款比較和同步SQL Server數(shù)據(jù)庫結(jié)構(gòu)的工具。現(xiàn)有超過150,000的數(shù)據(jù)庫管理員、開發(fā)人員和測(cè)試人員在使用它。當(dāng)測(cè)試本地?cái)?shù)據(jù)庫,暫存或激活遠(yuǎn)程服務(wù)器的數(shù)據(jù)庫時(shí),SQL Compare將分配數(shù)據(jù)庫的過程自動(dòng)化。
數(shù)據(jù)庫開發(fā)永遠(yuǎn)不會(huì)是一個(gè)容易的過程,但是如果給數(shù)據(jù)庫指定版本號(hào),那么很多人的工作就會(huì)變得更輕松,您可以通過一種簡單的方法來驗(yàn)證是否始終可以構(gòu)建數(shù)據(jù)庫以及每個(gè)版本的來源源代碼中保留了將遷移腳本從上一個(gè)版本遷移到下一個(gè)版本的功能。開發(fā)工作是一個(gè)團(tuán)隊(duì)過程,所有內(nèi)容都必須可見且可重復(fù)。
數(shù)據(jù)庫版本和版本管理
無論以何種方式完成數(shù)據(jù)庫的開發(fā)工作,開發(fā)團(tuán)隊(duì)都將在某個(gè)時(shí)候確定發(fā)布該數(shù)據(jù)庫的版本。此版本將由版本控制中的腳本表示。經(jīng)過適當(dāng)?shù)膯卧图蓽y(cè)試后,數(shù)據(jù)庫的版本將成為候選版本。為什么使用“候選人”一詞?因?yàn)樗赡軣o法通過部署管道一直到生產(chǎn)的一個(gè)或多個(gè)后續(xù)測(cè)試或檢查。
一旦某個(gè)版本成為發(fā)行候選版本,就必須保護(hù)它不受任何修改,否則后續(xù)測(cè)試將無效。任何自動(dòng)化的DevOps流程都需要能夠檢查其是否使用了正確的未更改版本。該版本在數(shù)據(jù)庫中的明顯位置是將其作為擴(kuò)展屬性附加到數(shù)據(jù)庫。最好根據(jù)源代碼管理或NuGet包中版本的副本進(jìn)行檢查。
那么,這些DevOps流程是什么?一旦開發(fā)數(shù)據(jù)庫構(gòu)建成為候選版本,它將進(jìn)入通常稱為“部署管道”的過程。這是一個(gè)錯(cuò)誤的稱呼,因?yàn)樗馕吨看螜z查都必須順序進(jìn)行。實(shí)際上,最好并行進(jìn)行。必須以多種方式測(cè)試候選發(fā)布版,以確保其足夠健壯,合法,能夠滿足客戶的期望以及滿足客戶的需求。除了通常對(duì)每個(gè)構(gòu)建進(jìn)行的單元和集成測(cè)試之外,檢查所有這些內(nèi)容還涉及非常不同的測(cè)試范圍。完成所有這些檢查之后,數(shù)據(jù)庫就可以進(jìn)行登臺(tái)了。如果它可以分階段通過所有測(cè)試,那是可以合法測(cè)試真實(shí)數(shù)據(jù)的少數(shù)幾個(gè)地方之一,那么就可以放心地將其發(fā)布到生產(chǎn)環(huán)境中。
從我所說的內(nèi)容中,您會(huì)注意到,如果不進(jìn)行仔細(xì)的管理,此發(fā)布過程可能會(huì)變成“痛苦的世界”。許多數(shù)據(jù)庫需要與候選版本相同。測(cè)試單元還可以包括數(shù)據(jù)庫的先前版本。我經(jīng)歷過開發(fā)站點(diǎn),這些站點(diǎn)有多個(gè)版本,而其他地方根本不存在。
您已經(jīng)進(jìn)行了用戶驗(yàn)收測(cè)試,不僅必須存在運(yùn)行數(shù)據(jù)庫及其關(guān)聯(lián)的應(yīng)用程序,而且還要協(xié)調(diào)所有工作并以正確的版本進(jìn)行操作。然后是暫存,在此您再次需要當(dāng)前的暫存數(shù)據(jù)庫服務(wù)器來將候選發(fā)布以及生產(chǎn)數(shù)據(jù)放置到位。如果此過程中涉及的任何數(shù)據(jù)庫版本都不正確,則發(fā)布過程將失敗,因?yàn)闊o法進(jìn)行一項(xiàng)或多項(xiàng)要求的檢查,或者更糟的是,對(duì)于錯(cuò)誤的版本進(jìn)行了檢查。
在開發(fā)中,您需要掌握數(shù)據(jù)才能快速工作,而部署中則是另一回事。您可以構(gòu)建一個(gè)dev數(shù)據(jù)庫并復(fù)制所需的任何數(shù)據(jù),但是測(cè)試數(shù)據(jù)庫或UAT數(shù)據(jù)庫將需要精心策劃的數(shù)據(jù)。要更新或回滾這樣的數(shù)據(jù)庫,您需要一個(gè)遷移腳本。每個(gè)新發(fā)行版都需要一個(gè)遷移腳本,該腳本會(huì)將先前發(fā)行的版本更改為新發(fā)行版。因?yàn)樗鼉H對(duì)目標(biāo)數(shù)據(jù)庫的特定版本有效,所以它需要檢查目標(biāo)的版本并僅在目標(biāo)版本正確時(shí)運(yùn)行。這是發(fā)行版所需的唯一遷移腳本,盡管俗世也將添加反方向運(yùn)行的回滾腳本。
使用SQL Compare的遷移腳本作為起點(diǎn)
創(chuàng)建一個(gè)有效的腳本來在版本之間遷移數(shù)據(jù)庫應(yīng)該是一個(gè)簡單的過程,但是不要指望它。候選發(fā)布版本將與生產(chǎn)版本有所不同。如果您已經(jīng)重新設(shè)計(jì)了表結(jié)構(gòu),或者重命名了許多例程,列或表,那么您的模式比較工具可能無法始終如您所愿地工作。它將需要幫助來保存現(xiàn)有數(shù)據(jù)。如果不能,它可能會(huì)通知您,但可能不會(huì)。
那你該怎么辦 第一個(gè)本能是手工剪切遷移腳本。我退縮了,只是在想,因?yàn)榧?xì)節(jié)很重要,惡魔潛伏在那里。忘記所有與大型變更同時(shí)進(jìn)行的細(xì)微變更非常容易,您要么過分樂觀,部署失敗,要么被困在幾乎無法修改的修改-測(cè)試-修改-測(cè)試周期中確保遷移腳本有效。我的首選是建立并修改自動(dòng)生成的遷移腳本,該腳本是模式比較的輸出,由SQL Compare完成。這是因?yàn)镾QL Compare(通過檢查它生成的腳本會(huì)注意到)能夠進(jìn)行許多巧妙的遷移,而簡單的手工剪切ALTER腳本會(huì)失敗。
盡管遷移腳本是您在部署管道中使用的腳本,但重要的是不要在開發(fā)過程中因遷移問題而過于分散注意力。數(shù)據(jù)庫開發(fā)人員應(yīng)該能夠進(jìn)行很多逐步改進(jìn),甚至沉迷于實(shí)驗(yàn),而不必?fù)?dān)心下游麻煩。您可以將所有次要內(nèi)容委托給構(gòu)建過程。即使當(dāng)您從根本上更改表時(shí),SQL Compare有時(shí)有時(shí)無法介意您的意圖,它仍然會(huì)占用所有較小的內(nèi)容。您需要做的就是添加棘手的遷移代碼,該代碼很可能已經(jīng)被開發(fā)人員剪切和測(cè)試,作為特定的遷移腳本。畢竟,開發(fā)人員無論如何都必須這樣做以修改其測(cè)試數(shù)據(jù),以準(zhǔn)備在開發(fā)過程中測(cè)試每個(gè)新版本的構(gòu)建。
您需要了解的一些SQL比較約定
SQL Compare自動(dòng)生成一個(gè)遷移腳本,該腳本將使目標(biāo)數(shù)據(jù)庫的架構(gòu)與源數(shù)據(jù)庫的架構(gòu)匹配。它旨在確保此腳本成功完成或回滾,不留下任何痕跡。為此,它會(huì)在每個(gè)DDL語句(例如或)之后檢查錯(cuò)誤級(jí)別CREATE,并且如果發(fā)生了不會(huì)導(dǎo)致腳本立即回滾或終止的錯(cuò)誤,它將設(shè)置連接狀態(tài),直到該操作不再執(zhí)行。最終使用。例如:ALTERGRANTIF @@ERROR <> 0 SET NOEXEC ON
RINT N'Altering [dbo].[byroyalty]' GO ALTER PROCEDURE [dbo].[byroyalty] @percentage int AS select au_id from titleauthor where titleauthor.royaltyper = @percentage GO IF @@ERROR <> 0 SET NOEXEC ON GO
腳本末尾有非常重要的批處理,可以捕獲任何錯(cuò)誤。
DECLARE @Success AS BIT SET @Success = 1 SET NOEXEC OFF IF (@Success = 1) PRINT 'The database update succeeded' ELSE BEGIN IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION PRINT 'The database update failed' END
如果此時(shí)SQL Server仍在執(zhí)行代碼,它將聲明一個(gè)名為的變量@success并將其設(shè)置為true。然后,它將設(shè)置連接以執(zhí)行代碼,而不管是否存在錯(cuò)誤。如果將變量成功設(shè)置為true,則遷移腳本被視為成功。否則,任何事務(wù)都會(huì)回滾,并且更新失敗。
要成為一個(gè)體貼的參與者,在適應(yīng)此腳本時(shí),您將需要在每個(gè)DDL SQL語句之后檢查錯(cuò)誤變量,并設(shè)置NOEXEC ON是否存在會(huì)影響遷移的錯(cuò)誤。切勿NOEXEC OFF在更改SQL比較腳本時(shí)在使用的代碼中進(jìn)行設(shè)置!
在數(shù)據(jù)庫上標(biāo)記版本
“版本化”數(shù)據(jù)庫的唯一確定方法是通過擴(kuò)展屬性在數(shù)據(jù)庫上標(biāo)記版本。尚無確定的標(biāo)準(zhǔn)。在準(zhǔn)備第一個(gè)定制SQL Compare腳本的示例時(shí),讓我們獲得一種就地對(duì)數(shù)據(jù)庫進(jìn)行版本控制的簡單方法。稍后,這將使我們能夠適當(dāng)?shù)厥褂眠w移腳本,而無需進(jìn)行詳盡的檢查。
這是一些代碼,可讓您在數(shù)據(jù)庫(在本例中為Pubs數(shù)據(jù)庫)中設(shè)置版本號(hào)。
SET NOEXEC off go USE pubs DECLARE @DatabaseInfo NVARCHAR(3750), @version NVARCHAR(20) SET @version=N'2.1.5' SELECT @DatabaseInfo = ( SELECT 'Pubs' AS "Name", @version AS "Version", 'The Pubs (publishing) Database supports a fictitious bookshop.' AS "Description", GetDate() AS "Modified", SUser_Name() AS "by" FOR JSON PATH ); IF not EXISTS (SELECT name, value FROM fn_listextendedproperty( N'Database_Info',default, default, default, default, default, default) ) EXEC sys.sp_addextendedproperty @name=N'Database_Info', @value=@DatabaseInfo ELSE EXEC sys.sp_Updateextendedproperty @name=N'Database_Info', @value=@DatabaseInfo
創(chuàng)建Database_Info擴(kuò)展屬性后,我們現(xiàn)在可以使用版本標(biāo)記原始數(shù)據(jù)庫。在開發(fā)數(shù)據(jù)庫的新版本時(shí),我們可以很簡單地將相同版本的圖章和更新的版本號(hào)放在同一位置。如果在事務(wù)中完成,它將在成功遷移后自動(dòng)復(fù)制到目標(biāo)。
在GitHub中,在提交源代碼之前,我們可以在version.json文件中維護(hù)數(shù)據(jù)庫的版本號(hào),并將其設(shè)置為正確的版本號(hào)。該版本號(hào)將不在對(duì)象級(jí)源中,因?yàn)樗菙?shù)據(jù)庫本身的屬性。但是,如果您使用實(shí)時(shí)數(shù)據(jù)庫作為源,它將在遷移腳本中。上面的代碼在Github中為AddInitialVersion.sql。
建立實(shí)踐實(shí)驗(yàn)室
為了進(jìn)行簡單的演示,我們將從好奇的柜子中取出古老的pubs數(shù)據(jù)庫,并將其安裝為“假裝”生產(chǎn)服務(wù)器。我們將創(chuàng)建一個(gè)Github項(xiàng)目,其目的是使數(shù)據(jù)庫更新一些。
我們會(huì)假裝我們的Pubs數(shù)據(jù)庫的“生產(chǎn)”副本(當(dāng)前版本)的版本為2.1.5,因此將其標(biāo)記為該版本。這是一個(gè)只讀參考數(shù)據(jù)庫,可用作測(cè)試數(shù)據(jù)的源,并用于在開發(fā)過程中運(yùn)行測(cè)試時(shí)檢查數(shù)據(jù)是否未更改。pubs的備份在這里。
要在其上標(biāo)記版本,可以使用此方法,它假定Database_Info擴(kuò)展屬性尚不存在。
EXEC sp_addextendedproperty N'Database_Info', N'[{"Name":"Pubs","Version":"2.1.5","Description":"The Pubs (publishing) Database supports a fictitious bookshop.","Modified":"2020-05-06T13:57:56.217","by":"PhilFactor"}]', NULL, NULL, NULL, NULL, NULL, NULL;
為了模擬開發(fā)過程,我們將在開發(fā)服務(wù)器上安裝原始Pubs數(shù)據(jù)庫的另一個(gè)副本,并在生產(chǎn)中使用當(dāng)前 版本。這表示起始版本,即您要更改以創(chuàng)建新版本的版本。通過引用當(dāng)前版本(以及當(dāng)前發(fā)行版),您可以隨時(shí)了解遷移腳本需要實(shí)現(xiàn)的目標(biāo)。對(duì)于某些團(tuán)隊(duì)來說,這可能是一個(gè)共享的開發(fā)數(shù)據(jù)庫。
相關(guān)產(chǎn)品推薦:
SQL Prompt:SQL語法提示工具
SQL Toolbelt:Red Gate產(chǎn)品套包
SQL Monitor:SQL Server監(jiān)控工具
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: