[一]串連問題(舉例)
[Microsoft Access]
constr = "DBQ=c:\data\clwz.mdb; DRIVER={Microsoft Access Driver (*.mdb)}"
[Microsoft Sql Server]
constr = "DRIVER={SQL Server};SERVER=host;DATABASE=mydata;uid=sa;pwd="
[二]相似函數(舉例)
[1]DATEDIFF(datepart, startdate, enddate)
其中“datepart”參數可選項如下:
設定 描述
————————————
[Microsoft Access]
年 yyyy
季度 q
月 m
一年的日數 y
日 d
一周的日數 w
周 ww
小時 h
分鐘 n
秒 s
[Microsoft Sql Server]
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
hour hh
minute mi, n
second ss, s
millisecond ms
基本上差不多,但注意的是在寫的時候
[Microsoft Access]要加引號,如:datediff('d',enddate,'2004/08/01') [Microsoft Sql Server]則不需要,如:datediff(d,enddate,'2004/08/01')
[2][Microsoft Access]中可用如cstr等轉資料類型函數,而 [Microsoft Sql Server]中則用convert或cast函數,如: convert(varchar,[amount])等。
[3][Microsoft Sql Server] 取目前時間用getdate等等...
[三]語句 [Microsoft Sql Server] 可以用
CASE
WHEN THEN
WHEN THEN
...
ELSE
END
語句,而 [Microsoft Access] 不支援。
[Microsoft Access]也不支援between語句
[Microsoft Sql Server]則可以這樣寫:
[date] between @date1 and @date2
[四]查詢表
[Microsoft Sql Server] 可三個及以上表join查詢,而 [Microsoft Access] 好像只能兩個表聯結查詢(待權威確認),而且[Microsoft Sql Server]可用“*=”和“=*”串連符。
[五]除零問題
[Microsoft Access] 在碰到除數為零時,自動丟掉相關記錄,而 [Microsoft Sql Server]
則會報錯,且查詢中止。刪除代碼:[Microsoft Access] 可以這樣寫:
delete * from [table]
[Microsoft SQL Server]
只能這樣寫:
delete from [table]
多*會報錯
當前日期: [Microsoft Access] 用date() [Microsoft SQL Server] 用getdate()如果資料庫可能會更換類型的話,可以 在ASP代碼中加上如這樣:
if inStr(constr,"Microsoft Access") > 0 then
sqlstr=[Microsoft Access][sql代碼]
else
sqlstr=[Microsoft Sql Server][sql代碼]
end if
(constr--連接字串)
這樣即使改了資料庫,也不用改資料庫查詢更新代碼了。 再加:access中有true、false的欄位記錄,而sql裡只有smallint,對應如果在access裡有“欄位名=true”的,在sql 裡要改成“欄位名=1” 網上大部分的免費asp程式使用的是access資料庫。但是access資料庫作為一個中小型的單機資料庫系統,在承擔訪問量、資料量大的網站應用程式時, 往往就不堪重負了。
一般認為,超過50M的access資料庫效能就開始明顯下降,超過100M以後,出錯、運行慢的問題會更加突出。儘管可以如動網7.0以後那樣,從程式的角度盡量最佳化以圖提高效能,但是不能從根本上解決問題。
這時也許使用微軟的SQL Server資料庫就是最可能的辦法,當然也可以使用其它的如Oracle、MySQL等等,但是作為改寫來說,由於同為微軟的產品,改寫成SQL Server應該是最省力的辦法。
一、改寫前提:
系統已經安裝好SQL Server2000並且打上了SP3補丁;安裝好Office套件裡面的Access;使用一個支援純文字編輯並且帶有行號顯示的編輯器,推薦Ultra Edit,當然也可以使用FrontPage2003,不過以前的版本行號顯示不太好用。
個人能力要求:會基本的asp文法、access資料庫的操作、SQLServer企業管理器的基本操作。
二、資料庫的準備
一般來說有兩種情況:
1、程式提供了SQL資料庫格式:有一個MDF檔案,或者提供了建立SQL資料庫的SQL指令檔(尾碼名為.sql)。
如果有mdf檔案,可以用企業管理器直接附加上,如果提供的是sql指令檔,那麼就先用企業管理器自己建立一個sql資料庫,然後資料庫用企業管理器中的查詢分析器運行這個指令碼建立資料庫表。 這樣建立的資料庫基本不用再去改寫什麼了。
2、更多的是沒有提供SQL資料庫或指令檔的,這時,就要自己來做這一切了,這也是我們這個文章主要解決的問題。一般這樣的程式會提供一個access資料庫,這樣你就用企業管理器匯入access資料庫,匯入後需要改寫下面一些東西:
對照原來的access,改寫下面的部分:
(1)sql資料庫表是沒有自動欄位的,因此原來access中的自動欄位被轉換成了普通欄位,需要手工改成標識類型,增量為1。
(2)所有的時間欄位,如果定義了預設值,那麼原來肯定是now(),需要改成getdate()
(3)原來欄位的預設值一般都不會自動引入,需要對照原表的欄位手工添加。
(4)由於資料庫的不同,access和sql的欄位類型很多轉換後就變化了,比如原來的《是否》欄位會被轉換成bit或者int,備忘欄位被轉換 成longtext,text欄位轉換成varchar等等,一般來說不會影響程式運行,如果有問題,我們在下面的程式改寫部分再說。
(5)如果你要用一個For SQL的程式,裡面用到了預存程序,那麼你應該有這個程式本身建立SQL資料庫的方法:有其本身的SQL資料庫檔案, 或者sql指令碼;如果沒有的話,採用匯入access資料庫的方式是無法建立預存程序的,這樣你最好放棄這個For SQL的程式版本,使用同樣版本的 For Access的程式,匯入access資料庫,然後用下面的改寫方法自己改成SQL版本的程式。
三、連接字串的改寫
可參考動網的這段,分別是針對access和SQL的
Dim ConnStr
If IsSqlDataBase = 1 Then
'sql資料庫連接參數:資料庫名、使用者密碼、使用者名稱、串連名(本地用local,外地用IP)
Dim SqlDatabaseName,SqlPassword,SqlUsername,SqlLocalName
SqlDatabaseName = "dvbbs7"
SqlPassword = ""
SqlUsername = "dvbbs"
SqlLocalName = "(local)"
ConnStr = "Provider = Sqloledb; User ID = " & SqlUsername & "; Password = " & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source = " & SqlLocalName & ";"
Else
'免費使用者第一次使用請修改本處資料庫地址並相應修改data目錄中資料庫名稱,如將dvbbs6.mdb修改為dvbbs6.asp
Db = "data/fengerqingqing.mdb"
ConnStr = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = " & Server.MapPath(db)
End If
On Error Resume Next
Set conn = Server.CreateObject("ADODB.Connection")
conn.open ConnStr
當然你使用SQL的話,有關access的使用語句可以刪除,就是else後面到on error resume next前面,變成這樣:
Dim ConnStr
'sql資料庫連接參數:資料庫名、使用者密碼、使用者名稱、串連名(本地用local,外地用IP)
Dim SqlDatabaseName,SqlPassword,SqlUsername,SqlLocalName
SqlDatabaseName = "dvbbs7"
SqlPassword = ""
SqlUsername = "dvbbs"
SqlLocalName = "(local)"
ConnStr = "Provider = Sqloledb; User ID = " & SqlUsername & "; Password = " & SqlPassword & "; Initial Catalog = " & SqlDatabaseName & "; Data Source = " & SqlLocalName & ";"
On Error Resume Next
Set conn = Server.CreateObject("ADODB.Connection")
conn.open ConnStr
也可以簡潔一些,寫成這樣:
Set conn = Server.CreateObject("ADODB.Connection")
conn.open "Provider = Sqloledb; User ID = sa; Password = 1234567; Initial Catalog = dvbbs7; Data Source = (local);"
裡面的資料庫名稱、資料來源、使用者、密碼根據自己的實際情況改寫一下。
四、程式的改寫
這也有兩種情況
1、如果你幸運,拿到的是For SQL的程式,那麼如果上面的資料庫建立過程沒有遇到麻煩,程式基本上就可以運行了,出錯的話,只是程式本身的bug,如何修改不是這個文章討論的內容,就不贅述了。
2、大多數情況,程式本身是For Access的,與For SQL的程式差別主要是程式中使用到的SQL查詢語句。注意,SQL查詢語句是資料 庫應用不可缺少的部分,不管是For SQL還是For Aceess的程式使用的文法大體差不多,但是有一些微妙的差別,正是這些差別,造成了程式的不 通用,也是我們需要修改的主要內容。這樣一般要修改的部分如下:
(1)時間函數的問題:SQL資料庫的時間函數與access不同,最常見的是取現在時間的函數,access是now(),SQL是 getdate()。因此凡是在where子句中使用了now()的地方都要改成getdate();注意,now()函數在asp程式本身也要使用,凡 是不在資料庫查詢或執行語句中使用的now()函數千萬不要改。
(2)時間比較函數:datediff('d','時間1',‘時間2’)這是access查詢用的格式,SQl中這些引號都要去掉,同時時間格式的前後可能加上了#,這也要去掉。同樣這也是指在sql語句中的,在asp語句中的要保持原樣。
(3)空值的表示:在access中,判斷空值一般用是否=""來表示,但是這在SQL中往往出錯,如果遇到出錯的問題或者程式運行不正常,可以改成如這樣判斷:where (name is null)
(4)真假值判斷:access中可以用=true、=false來判斷,但是在SQL中就會出錯,因此在SQL查詢或執行語句中這類判斷要分別改 成=1、=0。注意一點:有些程式雖然寫成=“true”,但是由於有引號,所以這個欄位是字元類型的,你不能改成=1,保持原樣即可。
以上是比較常見的改寫的地方,還有一些不太常見,如果遇到了可以在此回帖討論。
五、程式的調試
前面推薦使用帶有行號的編輯器,是因為上述的改寫不大可能是直接搜尋程式源碼來做,很難找全。我採取的方式一般這樣:資料庫改寫完成,直接調試程 序,出錯後,看看出錯的提示,找到相應檔案的程式碼,但是根源往往不是那行,比如出錯的語句是:conn.execute(sql),但是這句本身是沒有 錯的,錯誤原因是裡面的這個sql字串,那就向上看這個sql字串是如何產生的,按照上面所說的程式修改辦法修改。
資料庫匯入以後,自動增加欄位需要重寫,所有的數字類型需要增加長度,最好用decimal。
所有的預設值都丟失了。主要是數字類型和日期類型。
所有now(),time(),date()要改成getdate()。
所有datediff('d', time1, time2)要改成datediff(day, time1, time2)
有可能一些true/false類型不能使用,要變為1/0。
備忘類型要通過cast(column as varchar)來使用。
CursorType要改成1,也就是開啟資料庫時要給出第一個數字參數為1,否則記錄可能顯示不完整。
isnull(rowname)要改成rowname = null
ACCESS的資料庫中的自動編號類型在轉化時,sql server並沒有將它設為自動編號型,我們需在SQL建立語句中加上identity,表示自動編號!
轉化時,跟日期有關的欄位,SQL SERVER預設為smalldatetime型,我們最好將它變為datetime型,因為datetime型的範圍比smalldatetime型 大。有時用smalldatetime型時,轉化失敗,而用datetime型時,轉化成功。
對此兩種資料庫進行操作的sql語句不全相同,例如:在對ACCESS資料庫進行刪除紀錄時用:"delete * from user where id=10",而對SQL SERVER資料庫進行刪除是用:"delete user where id=10".
日期函數不相同,在對ACCESS資料庫處理中,可用date()、time()等函數,但對SQL SERVER資料庫處理中,只能用datediff,dateadd等函數,而不能用date()、time()等函數。
在對ACCESS資料庫處理中,sql語句中直接可以用一些VB的函數,像cstr()函數,而對SQL SERVER資料庫處理中,卻不能用。
下表比較了MicrosoftAccess資料庫(MicrosoftAccess資料庫:資料和對象(如表、查詢或表單)組成的集合,與特定的主 題或用途有關。MicrosoftJet資料庫引擎用於管理資料。)和MicrosoftAccess項目(MicrosoftAccess項目:與 MicrosoftSQLServer資料庫連接且用於建立客戶/伺服器應用程式的Access檔案。專案檔中不包含任何資料或基於資料定義的對象(如 表或視圖)。)的資料類型(資料類型:決定欄位可擁有的資料類型的欄位特徵。資料類型包括Boolean、Integer、Long、Currency、 Single、Double、Date、String和Variant(預設))。
MicrosoftAccess資料類型SQLServer資料類型
是/否(“是/否”資料類型:一種欄位資料類型,用於只有兩種可能值(如是或否、True或False)的欄位。不允許有Null值。)bit(bit資料類型:在Access項目中,一種儲存值為1或0的資料類型。接受1和0以外的整數值,但總是將其解釋為1。)
數字(“數字”資料類型:MicrosoftAccess資料庫中的一種欄位資料類型,用於將在數學運算中使用的數值資料。但是,若要顯示或計算貨 幣值,則應使用“貨幣”資料類型。)(位元組)tinyint(tinyint資料類型:Access項目中的一種佔一個位元組(8位)的資料類型,用於儲存 從0到255範圍內的整數。)
數字(整型)smallint(smallint資料類型:Access項目中的一種2位元組(16位)資料類型,儲存位於-2^15(-32,768)與2^15-1(32,767)之間的數字。)
數字(長整型)int(int資料類型:Access項目中的一種4位元組(32位)資料類型,儲存位於-2^31(-2,147,483,648)與2^31-1(2,147,483,647)之間的數字。)
數字(單精確度浮點型)real(real資料類型:在Access項目中,一種近似的數值資料類型,精度為7位,正值取值範圍大致從1.18E-38到3.40E+38,負值取值範圍大致從-1.18E-38到-3.40E+38,也可以取0。)
(無等價的資料類型)bigint(bigint資料類型:Access項目中的一種8位元組(64位)資料類型,儲存位於-2^63(- 9,223,372,036,854,775,808)與2^63-1(9,223,372,036,854,775,807)之間的數字。)
數字(雙精確度浮點型)float(float資料類型:在Access項目中,一種近似的數值資料類型,精度為15位。它所儲存的正值範圍大致是從2.23E-308到1.79E+308,負值範圍大致是從-2.23E-308到-1.79E+308,也可以為0。)
貨幣(“貨幣”資料類型:MicrosoftAccess資料庫中的一種資料類型,用於與貨幣有關的計算或其精確度極其重要的定點計算。) money(money資料類型:在Access項目中,用於儲存貨幣值的資料類型,取值範圍從-922,337,203,685,477.5707到 922,337,203,685,477.5807,精確度為萬分之一個貨幣單位。)
smallmoney(smallmoney資料類型:Access項目中的一種儲存貨幣值的資料類型,取值範圍從-214,748.3648到214,748.3647,精確度為萬分之一個貨幣單位。當顯示smallmoney值時,會將它們四捨五入為兩個小數位。)
小數/數值(decimal資料類型(Access資料庫):精確的數值資料類型,用於儲存-10^38-1到10^38-1的值。可以指定數值範 圍(最大總位元)和精度(小數點右邊的最大位元)。)decimal(decimal資料類型(Access項目):精確的數值資料類型,用於儲存- 10^38-1到10^38-1的值。可以指定數值範圍(最大總位元)和精度(小數點右邊的最大位元)。)
numeric(numeric資料類型:在Access項目中,一種精確的數值資料類型,取值從-10^38-1到10^38-1。可以指定數值範圍(最大總位元)和精度(小數點右邊的最大位元)。)
日期/時間(“日期/時間”資料類型:Access資料庫的一種資料類型,用來存放日期和時間資訊。)datetime(datetime資料類 型:在Access項目中,日期和時間的資料類型,範圍從1753年1月1日到9999年12月31日,精確度為三百分之一秒,即3.33毫秒。)
smalldatetime(smalldatetime資料類型:Access項目中的一種日期和時間資料類型,精度不如datetime時間資料類型。資料取值範圍從1900年1月1日到2079年6月6日,精確度為一分鐘。)
自動編號(“自動編號”資料類型:MicrosoftAccess資料庫中的一種欄位資料類型,當向表中添加一條新記錄時,這種資料類型會自動為每 條記錄儲存一個唯一的編號。可以產生三種編號:順序號、隨機號和同步複製ID。)(遞增)int(int資料類型:Access項目中的一種4位元組(32 位)資料類型,儲存位於-2^31(-2,147,483,648)與2^31-1(2,147,483,647)之間的數字。)(定義了 Identity屬性)
文本(“文本”資料類型:MicrosoftAccess資料庫中的一種欄位資料類型。“文本”資料類型最多可以包含255個字元,或者是由 FieldSize屬性指定的一個小一些的字元數。)(n)varchar(n)(varchar(n)資料類型:Access項目中的一種可變長度的數 據類型,最大長度為8,000個ANSI字元。)
nvarchar(n)(nvarchar(n)資料類型:在Access項目中,一種可變長度的資料類型,最多可含4,000個Unicode字元。Unicode字元每字元佔兩個位元組,而且支援所有國際字元。)
備忘(“備忘”資料類型:在MicrosoftAccess資料庫中的一種欄位資料類型。“備忘”欄位最多可以包含65,535個字元。)text (text資料類型:Access項目中的一種長度可變的資料類型,最多可儲存2^31-1(2,147,483,647)個字元;預設長度為16。)
OLE對象(“OLE對象”資料類型:欄位的資料類型之一,用於在其他應用程式中建立的、可連結或嵌入(插入)到Access資料庫中的對象。) image(image資料類型:在Access項目中,一種長度可變的資料類型,最多可儲存2^31-1(2,147,483,647)位元組的位元 據。image資料類型用來儲存BLOB(二進位大對象),片、文檔、聲音和已編譯代碼。)
同步複製ID(又名通用唯一識別碼(GUID:在Access資料庫中,一種用於建立同步複製唯一識別碼的16位元組欄位。GUID用於標識副本、副 本集、表、記錄和其他對象。在Access資料庫中,GUID是指同步複製ID。)(GUID))uniqueidentifier (uniqueidentifier資料類型:在Access項目中,16位元組的通用唯一識別碼(GUID)。)(僅適於SQLServer7.0或更高 版本)
超連結(超連結資料類型:儲存超連結位址的Access資料庫欄位的資料類型。地址最多可以包含四部分,用以下文法格式編寫:displaytext#address#subaddress#。)
char(char資料類型:在Access項目中,一種固定長度的資料類型,最多可含8,000個ANSI字元。), nchar(nchar資料類型:在Access項目中,一種固定長度的資料類型,最多可含4,000個Unicode字元。Unicode字元每字元占 兩個位元組,而且支援所有國際字。),varchar,nvarchar(Hyperlink屬性設為Yes)
(無等價的資料類型)varbinary(varbinary資料類型:Access項目中的一種可變長度的資料類型,最多可儲存8,000位元組的位元據。)
(無等價的資料類型)smallint(smallint資料類型:Access項目中的一種2位元組(16位)資料類型,儲存位於-2^15(-32,768)與2^15-1(32,767)之間的數字。)
(無等價的資料類型)timestamp(timestamp資料類型:在Access項目中,一種每插入或更新一行就會自動更新的資料類型。 timestamp列中的值不是datetime資料,而是binary(8)或varbinary(8),標明了資料修改的順序。)
(無等價的資料類型)charnchar
(無等價的資料類型)sql_variant(sql_variant資料類型:Access項目中的一種資料類型,儲存除text、ntext、 image、timestamp和sql_variant類型以外的多種資料類型的值。在列、參數、變數或使用者定義函數的傳回值中使用。)
(無等價的資料類型)使用者定義(使用者定義的資料類型:在MicrosoftSQLServer資料庫中,允許某列包含的資料的類型定義,由使用者利用現有的系統資料類型定義。規則和預設值僅可以綁定到使用者定義的資料類型。)
注釋在Access項目或SQLServer資料庫中,首碼“n”代表“省/地區”,意思是這個資料類型是啟用Unicode的。在Access資料庫中,全部文本列在預設情況下都是啟用Unicode的。