解析用SSMA移植Acceses到SQL幾點(diǎn)問(wèn)題

字號(hào):

這些年來(lái),Access數(shù)據(jù)庫(kù)一直在PC平臺(tái)占據(jù)主導(dǎo)地位,使用它建立了大量的部門(mén)數(shù)據(jù)庫(kù)。隨著這些數(shù)據(jù)庫(kù)的應(yīng)用,它們中的大多數(shù)已經(jīng)慢慢地具有應(yīng)急使命,現(xiàn)在需要的是加固成為一個(gè)安全的客戶(hù)端—服務(wù)器引擎。
    在微軟想要統(tǒng)治世界的偉大計(jì)劃中,更希望這種引擎是SQL Server。隨著這種想法,微軟針對(duì)Access提供了免費(fèi)的SQL Server移植工具——SSMA。
    對(duì)于開(kāi)發(fā)者來(lái)說(shuō),移植工具已有很大的實(shí)惠。但期望這種工具能夠移植整個(gè)應(yīng)用程序是不現(xiàn)實(shí)的,因?yàn)锳ccess有一些SQL Server所沒(méi)有的簡(jiǎn)單工具(例如窗體和報(bào)表性能)。但是我們有理由相信這種工具能做大部分工作,比如建立適當(dāng)?shù)谋恚D(zhuǎn)移數(shù)據(jù),把查詢(xún)轉(zhuǎn)換成視圖等。
    SSMA的運(yùn)行需要在.NET Framework2.0版本以上,J#2.0可重組包以及至少1GB RAM。
    SSMA具有一個(gè)清晰的圖形用戶(hù)界面,分成四個(gè)面板。在建立一個(gè)新工程之后,首先添加一個(gè)或多個(gè)Access數(shù)據(jù)庫(kù),然后連接到適當(dāng)?shù)腟QL Server數(shù)據(jù)庫(kù),下一步就是把架構(gòu)(schema)轉(zhuǎn)換成SQL Server。
    注意,這個(gè)過(guò)程并不是運(yùn)行依靠SQL Server引擎的架構(gòu),而是簡(jiǎn)單地生成了一個(gè)在SSMA中可見(jiàn)的,可用的SQL Server架構(gòu),同時(shí)生成一個(gè)錯(cuò)誤、警告和信息標(biāo)記的集合。
    從這點(diǎn)來(lái)看,該工具的能力就顯而易見(jiàn)。作為一個(gè)開(kāi)始,這些標(biāo)記指出轉(zhuǎn)換問(wèn)題,例如:不支持Access的一些函數(shù)如DateDiff,所以不能轉(zhuǎn)換(當(dāng)然這些函數(shù)可以被轉(zhuǎn)換,但SSMA不能實(shí)現(xiàn))。
    你可以瀏覽Access架構(gòu),觀察正在計(jì)劃的類(lèi)型映射等等,當(dāng)然如果你不喜歡這種缺省映射,也完全可以改變它,或者根據(jù)特殊的工程甚至特殊的表來(lái)做改變。
    查詢(xún)是一個(gè)比較特別的情形。它們被轉(zhuǎn)換成SQL Server視圖:你可以編輯Access查詢(xún)?nèi)缓螽a(chǎn)生適當(dāng)?shù)腟QL Server代碼。這樣的編輯是發(fā)生在SSMA的架構(gòu)中,而不是在Access數(shù)據(jù)庫(kù)本身完成。
    你可以使用SSMA運(yùn)行依靠數(shù)據(jù)庫(kù)的SQL Server架構(gòu),它建立了一種結(jié)構(gòu)來(lái)保存數(shù)據(jù)以便你可以移植數(shù)據(jù)。理論上聽(tīng)起來(lái)很好,但是實(shí)際上是怎樣的呢?雖說(shuō)嘗試從任意一個(gè)數(shù)據(jù)庫(kù)引擎移植到另一個(gè)都是麻煩的,且這個(gè)工具可以免費(fèi)的為你做90%的工作,但它還存在一些缺陷。
    例如,雖然不是SQL標(biāo)準(zhǔn)的一部分,Access需要所有日期來(lái)包裝到hash記號(hào)中。不幸的是,SSMA看起來(lái)沒(méi)有考慮到這點(diǎn),這個(gè)疏忽的結(jié)果就是所有涉及到日期的查詢(xún)結(jié)果都不能成功轉(zhuǎn)換。下面是一個(gè)錯(cuò)誤信息的例子:
    /* * SSMA error messages: * A2SS0058: Following SQL statement is not supported and cannot be converted: * * SELECT DISTINCTROW EMPLOYEES.EmployeeNo, EMPLOYEES.FirstName, EMPLOYEES.LastName, EMPLOYEES.DateOfBirth, EMPLOYEES.DateEmployed * FROM EMPLOYEES * WHERE ((EMPLOYEES.DateOfBirth)>#1/1/1970#); * */PRINT ’ERROR: SSMA failed to convert the previous statement.’
    日期在數(shù)據(jù)庫(kù)中是很常見(jiàn)的,所以這個(gè)疏忽將會(huì)影響大多數(shù)數(shù)據(jù)庫(kù)轉(zhuǎn)換。但要解決并不困難,如下:
    SELECT EmployeeNo, FirstName, LastName, DateOfBirth FROM dbo.EMPLOYEES WHERE (DateOfBirth > CONVERT(DATETIME, ’1970-01-01’))
    從例子中返回正確的數(shù)據(jù)集。
    (我們可以討論一下是否是這樣,例如:CONVERT(DATETIME, ’1970-01-01 00:00:00’, 102)可能更恰當(dāng),但是不管怎么說(shuō),我們可以轉(zhuǎn)換數(shù)據(jù)處理),如果我們可以手動(dòng)地做,SSMA就應(yīng)該可以為我們做這件事。
    還有更糟糕的問(wèn)題:Access默認(rèn)是在文本周?chē)褂秒p引號(hào),例如:
    SELECT EMPLOYEES.EmployeeNo, EMPLOYEES.FirstName FROM EMPLOYEES WHERE ((EMPLOYEES.FirstName="Norma"));
    SQL Server不是這樣,它使用單引號(hào),如下:WHERE EMPLOYEES.FirstName=’Norma’;然而,SSMA保留了上面這樣的雙引號(hào)代碼,沒(méi)做任何改變。而且在架構(gòu)產(chǎn)生期間并沒(méi)有引發(fā)錯(cuò)誤提示,錯(cuò)誤提示只發(fā)生在把架構(gòu)加載到SQL Server數(shù)據(jù)庫(kù)的過(guò)程中。那時(shí),SSMA拋出一個(gè)錯(cuò)誤提示說(shuō)存在一個(gè)非法列名Norma,這樣視圖就不能加載到SQL Server中了。以上顯示出SSMA并沒(méi)有做足夠的語(yǔ)法檢查。
    再?gòu)?qiáng)調(diào)一下,Access默認(rèn)使用雙引號(hào),而SSMA卻不能處理如此簡(jiǎn)單平常的Access語(yǔ)法。這就像一個(gè)法語(yǔ)到英語(yǔ)的翻譯者可以處理語(yǔ)言中的大多數(shù)詞,卻為單詞“Bonjour”感到束手無(wú)策一樣。
    再一個(gè)例子,Access允許為字段添加規(guī)則約束,例如一個(gè)名為“Title”的字段可以接受的值可能只有Mr., Mrs., Miss., Ms等。但SQL Server不能準(zhǔn)確地支持同樣的類(lèi)型約束。非常明顯SSMA轉(zhuǎn)換這種約束規(guī)則為一個(gè)表約束。Brilliant,做的不錯(cuò),只是在代碼中丟失了字段名:
    ALTER TABLE [dbo].[NAMES] ADD CONSTRAINT [SSMA_CC$NAMES$Title$validation_rule] CHECK (In (’Mr.’,’Mrs.’,’Miss’,’Ms’,’Dr.’,’Prof.’))這不僅不能在架構(gòu)轉(zhuǎn)載到SQL Server時(shí)運(yùn)行,同時(shí)更不能產(chǎn)生一個(gè)錯(cuò)誤消息。最后一行的正確語(yǔ)法應(yīng)該是:CHECK (Title In (’Mr.’,’Mrs.’,’Miss’,’Ms’,’Dr.’,’Prof.’))
    那么,我們是否應(yīng)該從機(jī)器上刪除SSMA呢?當(dāng)然不,因?yàn)樗_實(shí)完全自動(dòng)地做了大量的工作,也提供了一個(gè)合理的環(huán)境,在那里可以看到問(wèn)題區(qū)域并做出整理。指出它的缺陷,只是期望SSMA能更好。