明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

手把手教你在ASP中使用SQL語句

[摘要]五花八門的SQL產(chǎn)品多得要命,或許你早顧不得其它甩開袖子就動(dòng)手干了。但你要同時(shí)采用ASP和SQL的話就可能會(huì)頭暈。MySQL、SQL Server和mSQL都是絕佳的SQL工具,可惜,在ASP的環(huán)境...

五花八門的SQL產(chǎn)品多得要命,或許你早顧不得其它甩開袖子就動(dòng)手干了。但你要同時(shí)采用ASP和SQL的話就可能會(huì)頭暈。MySQL、SQL Server和mSQL都是絕佳的SQL工具,可惜,在ASP的環(huán)境下你卻用不著它們來創(chuàng)建實(shí)用的SQL語句。不過,你可以利用自己掌握的Access知識(shí)以及相應(yīng)的Access技能,再加上我們的提示和技巧,相信一定能成功地在你的ASP網(wǎng)頁中加入SQL。


1. SELECT 語句

在SQL的世界里,最最基礎(chǔ)的操作就是SELECT 語句了。在數(shù)據(jù)庫工具下直接采用SQL的時(shí)候很多人都會(huì)熟悉下面的操作:
SELECT what
FROM whichTable
WHERE criteria

執(zhí)行以上語句就會(huì)創(chuàng)建一個(gè)存放其結(jié)果的查詢。

而在ASP頁面文件上,你也可以采用以上的一般語法,不過情況稍微不同,ASP編程的時(shí)候,SELECT 語句的內(nèi)容要作為字符串賦給一個(gè)變量:
SQL = "SELECT what FROM whichTable WHERE criteria"

好了,明白了ASP下SQL“說話”的方式,接下來如法炮制即可,只要滿足你的需要,傳統(tǒng)的SQL查詢模式和條件查詢都能派用場(chǎng)。

舉例說明,不妨假設(shè)你的數(shù)據(jù)庫內(nèi)有個(gè)數(shù)據(jù)表,名字是Products ,現(xiàn)在你想取出這個(gè)表里的全部記錄。然后你就編寫了下面的代碼:
SQL ="SELECT * FROM Products"

以上代碼——SQL語句的作用就是取出表內(nèi)的全部數(shù)據(jù)——執(zhí)行后將會(huì)選出數(shù)據(jù)表內(nèi)的全部記錄。不過,要是只想從表內(nèi)取出某個(gè)特定列,比如p_name。那就不能用 * 通配符了,這里得鍵入具體某列的名字,代碼如下:
SQL ="SELECT p_name FROM Products"

執(zhí)行以上查詢之后Products 表內(nèi)、p_name 列的內(nèi)容就會(huì)全被選取出來。


2. 用WHERE子句設(shè)置查詢條件

有的時(shí)候取出全部數(shù)據(jù)庫記錄也許正好滿足你的要求,不過,在大多數(shù)情況下我們通常只需得到部分記錄。這樣一來該如何設(shè)計(jì)查詢呢?當(dāng)然會(huì)更費(fèi)點(diǎn)腦筋了,何況本文也存心不想讓你去用那個(gè)什么勞什子的recordset。

舉個(gè)例子,假如你只打算取出p_name 記錄,而且這些記錄的名字必須以字母w打頭,那么你就要用到下面的WHERE 子句了:
SQL ="SELECT p_name FROM Products WHERE p_name LIKE 'W%'"

WHERE 關(guān)鍵詞的后面跟著用來過濾數(shù)據(jù)的條件,有了這些條件的幫助,只有滿足一定標(biāo)準(zhǔn)的數(shù)據(jù)才會(huì)被查詢出來。在以上的例子里,查詢的結(jié)果只會(huì)得到名字以w 打頭的p_name 記錄。

以上例子中,百分比符號(hào)(%)的含義是指示查詢返回所有w 字母打頭而且后面是任何數(shù)據(jù)甚至沒有數(shù)據(jù)的記錄條目。所以,在執(zhí)行以上查詢的時(shí)候, west 和 willow 就會(huì)從Products 表內(nèi)被選取出來并存放在查詢里。

就像你看到的那樣,只要仔細(xì)地設(shè)計(jì)SELECT 語句,你就可以限制recordset 中返回的信息量,多琢磨琢磨總能滿足你的要求。

這些啊還不過是掌握SQL用途剛起步。為了幫助你逐步掌握復(fù)雜的SELECT 語句用法,下面就讓我們?cè)賮砜匆幌玛P(guān)鍵的標(biāo)準(zhǔn)術(shù)語:比較運(yùn)算符,這些玩意都是你在構(gòu)筑自己的SELECT 字符串來獲得特定數(shù)據(jù)時(shí)要經(jīng)常用到的。

WHERE子句基礎(chǔ)
在開始創(chuàng)建WHERE 子句的時(shí)候,最簡單的方式是采用標(biāo)準(zhǔn)的比較符號(hào),它們是 < 、 <= 、 > 、 >= 、<> 和 =。顯然,你很快就能明白以下代碼的含義和具體運(yùn)行結(jié)果:
SELECT * FROM Products WHERE p_price >= 199.95
SELECT * FROM Products WHERE p_price <> 19.95
SELECT * FROM Products WHERE p_version = '4'

注意: 這里你會(huì)注意到,最后一個(gè)例句中的數(shù)字4周圍加了單引號(hào)。原因是這樣的,在這個(gè)例子中的 '4' 是文本類型而非數(shù)字類型。因?yàn)槟銜?huì)把 SELECT 語句放到引號(hào)中來把它作為一個(gè)值賦給變量,所以你也可以在語句中采用引號(hào)。

比較運(yùn)算符
比較運(yùn)算符指定從表內(nèi)取出數(shù)據(jù)的內(nèi)容范圍。你可以用它們來創(chuàng)建過濾器以便縮小recordset的范圍,促使其只保存給定任務(wù)下你關(guān)心的信息。

3. LIKE 、 NOT LIKE和 BETWEEN


你已經(jīng)在上面取出w打頭記錄的例子中看到了LIKE的用法。LIKE判定詞是一個(gè)非常有用的符號(hào)。不過,在很多情況下用了它可能會(huì)帶給你太多的數(shù)據(jù),所以在用到它之前最好先開動(dòng)腦筋多想想自己到底想獲得什么數(shù)據(jù)。假設(shè)你想取出5位數(shù)字的SKU號(hào)碼,而且其開頭是1結(jié)尾是5,那么你可以用下劃符(_)代替%符號(hào):
SQL = "SELECT * FROM Products WHERE p_sku LIKE '1___5'"

下劃符表示任意一個(gè)字符。所以在輸入“1 _ _ _ 5”的情況下,你的搜索就會(huì)限制在滿足特定模式的5位數(shù)范圍內(nèi)了。

假如你想反其道而行之,要找出所有不匹配“1_ _ _ 5”模式的SKU條目。那么你只需要在剛才語句例子中的LIKE前面加上NOT就可以了。

BETWEEN
假設(shè)你想取出一定范圍內(nèi)的數(shù)據(jù),而且你事先知道范圍的起點(diǎn)和終點(diǎn),那么你不妨采用BETWEEN 判斷詞,F(xiàn)在就讓我們假設(shè)你想選取給定表內(nèi)范圍在 1和 10之間的記錄。你可以如下使用BETWEEN:
…WHERE ID BETWEEN 1 AND 10

或者你也可以采用已經(jīng)熟悉的數(shù)學(xué)判斷字句:
…WHERE ID >= 1 AND ID >= 10


4. 聯(lián)合語句

我們到目前為止所談到的SQL語句相對(duì)較為簡單,如果再能通過標(biāo)準(zhǔn)的recordset循環(huán)查詢,那么這些語句也能滿足一些更復(fù)雜的要求。不過,何必非要拘泥在淺嘗則止的基礎(chǔ)水準(zhǔn)之上呢?你完全可以再增加其他一些符號(hào),比如AND、 OR和NOT來完成更強(qiáng)大的功能。

以下面的SQL語句為例:
SQL ="SELECT c_firstname, c_lastname, c_email FROM customers WHERE c_email IS
NOT NULL AND c_purchase = '1' OR c_purchase = '2' AND c_lastname LIKE
'A%'"

就你目前所掌握的SQL知識(shí),以上的例子也不難解釋,不過上面的語句并沒有很明白地讓你看清條件字句是如何膠合在單一SQL語句中的。

多行語句
在SQL語句不好懂的情況下,你不妨把整個(gè)語句分解為多行代碼,然后在現(xiàn)有變量基礎(chǔ)上逐步增加查詢語句的各個(gè)組成部分并把它存在同一變量內(nèi):
    SQL = "SELECT c_firstname, c_lastname, c_emailaddress, c_phone"
    SQL = SQL & " FROM customers"
    SQL = SQL & " WHERE c_firstname LIKE 'A%' and c_emailaddress NOT NULL"
    SQL = SQL & " ORDER BY c_lastname, c_firstname"
到了最后一句,SQL變量就包含了以下的完整SELECT 語句:
"SELECT c_firstname, c_lastname, c_emailaddress, c_phone FROM customers
WHERE c_firstname LIKE 'A%' and c_emailaddress NO NULL ORDER BY c_lastname,
c_firstname"

整句照上面分解之后顯然好讀多了!在進(jìn)行調(diào)試的時(shí)候,你或許更樂于多敲幾個(gè)字符把程序改得更好讀些。不過你可要記住了,在封閉引號(hào)之前或者在打開引號(hào)之后你需要增加空格,這樣才能保證字符串連接起來的時(shí)候你沒有把幾個(gè)詞湊到了一塊。
5. 開始執(zhí)行

在學(xué)會(huì)了SELECT語句的構(gòu)造和用途之后你就該學(xué)習(xí)如何使用它了。在你所掌握的數(shù)據(jù)庫工具下,這可能意味著你得按下某個(gè)寫著“執(zhí)行”字樣的按鈕。在ASP網(wǎng)頁上,可以立即執(zhí)行SQL語句也可以當(dāng)作存儲(chǔ)過程調(diào)用。

一旦創(chuàng)建了SQL 語句,你還得設(shè)法訪問其查詢結(jié)果。顯然,這里的關(guān)鍵就是ASP recordset。在使用非SQL的recordset時(shí),創(chuàng)建recordset的代碼通常如下所示:
Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open "customers", objConn, 0, 1, 2

如果你對(duì)ASP比較熟悉以上的代碼對(duì)你可就不陌生了,你應(yīng)該知道“customers”表示你打開數(shù)據(jù)庫內(nèi)一個(gè)數(shù)據(jù)表的名字。

打開recordset
為了充分利用你更為熟悉的SQL技能,你需要調(diào)整常規(guī)ASP網(wǎng)頁上最常采用的recordset:
 Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open SQL, objConn, 0, 1, 2

這里唯一的修改就是在objRec.Open,之后用包含SQL語句的變量代替了要查詢的數(shù)據(jù)表的名稱。

這種方法的優(yōu)點(diǎn)之一是你可以指定游標(biāo)類型(如以上0, 1 ,2 所示)。

執(zhí)行SQL
你可以用緊湊的一行代碼執(zhí)行SQL語句來創(chuàng)建recordset。以下是語法:
Dim objRec
set objRec = objConn.Execute(SQL)

在上例中,你所看到的SQL是你存放自己SQL SELECT 語句的變量。該代碼行“運(yùn)行”SQL語句(或者說對(duì)數(shù)據(jù)庫進(jìn)行查詢),選取數(shù)據(jù)并把數(shù)據(jù)存放在recordset 內(nèi),在上例中就是變量objRec。這種方法的主要缺點(diǎn)是你不能選擇自己想采用的游標(biāo)類型。相反,recordset總是用前向游標(biāo)打開。

因?yàn)橛螛?biāo)的緣故,你或許打算熟悉兩種創(chuàng)建recordset的方法。直接執(zhí)行查詢節(jié)省了鍵入字符所消耗的時(shí)間,但那樣的話你就得采用默認(rèn)的游標(biāo)了,這樣有可能遭遇經(jīng)常不能正常運(yùn)行的毛病。不管你具體采用哪種辦法,兩者之間的最大的差別也不外乎代碼精練與否。在不考慮你取得什么字段、你的標(biāo)準(zhǔn)是什么的前提下,也不管你如何存儲(chǔ)數(shù)據(jù),采用SQL式的recordset 在體積上會(huì)比ASP上打開的標(biāo)準(zhǔn)recordset 要小得多,更別提操作起來的簡易性了。畢竟,通過過濾數(shù)據(jù),你消除了耗費(fèi)時(shí)間的if-then 測(cè)試和可能用到的循環(huán)。

編寫測(cè)試用SQL
這里有個(gè)技巧,許多專業(yè)ASP程序員習(xí)慣在測(cè)試網(wǎng)頁的時(shí)候“編寫”自己的SQL語句。這樣做可以幫助你調(diào)試代碼,因?yàn)槟憧梢詮闹锌吹絺鬟f給服務(wù)器執(zhí)行的字符串。而你要做的無非是增加Response.WriteyourVariable 在屏幕上顯示有關(guān)信息。在你把和SQL有關(guān)的問題提交給ASP討論組的時(shí)候你就應(yīng)該附上這些信息。

6. 存儲(chǔ)查詢


當(dāng)你的查詢相對(duì)簡單的時(shí)候,每次從頭開始創(chuàng)建SQL語句也不費(fèi)什么工夫,不過,復(fù)雜的查詢就不同了,每次都從頭來會(huì)產(chǎn)生很多開發(fā)錯(cuò)誤。因此,一旦讓SQL順利地運(yùn)行起來,你最好把它們存起來,在需要時(shí)再調(diào)用它們。這樣,哪怕是一個(gè)簡單查詢你都能隨時(shí)用上存儲(chǔ)的查詢語句了。

假設(shè)你每周都要給團(tuán)隊(duì)做一次報(bào)告,指出目前存在的業(yè)務(wù)支持問題,這些數(shù)據(jù)需要從你的數(shù)據(jù)庫中選取,而且要按照日期選擇記錄,同時(shí)根據(jù)你所在團(tuán)隊(duì)所采用的支持問題的類別排序。一旦你設(shè)計(jì)了這一查詢,你何必以后每周都重新編寫一次呢?不要在你的HTML頁面上創(chuàng)建查詢,你應(yīng)該用你的數(shù)據(jù)庫工具創(chuàng)建查詢并且保存它。

然后你可以采用ActiveCommand 屬性把查詢插入到你的ASP網(wǎng)頁。頭一兩回你可能會(huì)覺得沒啥意思,其實(shí)也就幾行代碼而已:
Set objSQ = Server.CreateObject ("ADODB.Command")
objSQ.ActiveConnection = "databaseName"

objSQ.CommandText = "storedQueryName"
objSQ.CommandType = adCmdStoredProc

set objRec = objSQ.Execute

注意,采用adCmdStoredProc 表示你已經(jīng)在頁面上包含了adovbs.inc 文件。該文件定義了你可以按照名字而非數(shù)字進(jìn)行訪問的Access常數(shù)。只需要在頁面上包含該文件即可(<!--#INCLUDE -->),然后你就可以用adCmdStoredProc 這類名字了。這樣,將來你再看到的時(shí)候更容易理解以上被存儲(chǔ)的查詢到底是個(gè)什么意思。

7. ORDER BY

從Access數(shù)據(jù)庫中選取記錄有件最令人喪氣的事情,它們是以怎樣的順序輸入到數(shù)據(jù)庫內(nèi)就按照怎樣的順序出來。就算你在Access環(huán)境內(nèi)采用Sort By來改變記錄視圖,數(shù)據(jù)表內(nèi)的記錄順序也并沒有發(fā)生改變。


如果你正在使用ASPrecordset在網(wǎng)頁上寫出記錄,那么你或許知道亂紛紛的順序是多令人痛苦的事。但是你可能不得不經(jīng)常得面對(duì)這一問題,因?yàn)椴⒉淮嬖谑裁春唵畏奖愕慕鉀Q方案。好在ORDER BY 可以簡化這一難題。

為了對(duì)你的結(jié)果排序,只要在SELECT語句末尾加上ORDER BY,然后指定你需要排序的參照列即可。因此,如果你想要根據(jù)顧客的姓氏對(duì)Customers表排序,那么你可以編寫如下的查詢語句:
SQL = "SELECT c_lastname, c_firstname, c_email FROM Customers ORDER BY c_lastname"

這樣,只要你建立了recordset而且開始把結(jié)果寫到屏幕上,你就會(huì)看見數(shù)據(jù)按照字母順序排列起來了。

多級(jí)排序
其實(shí)不僅僅可以在SQL語句中進(jìn)行一級(jí)排序。實(shí)際上,在很多情況下,你可能會(huì)希望指定兩到三級(jí)深度的數(shù)據(jù)排序。假設(shè)你有以下數(shù)據(jù)表,其內(nèi)容如下所示:


先前采用的單級(jí)ORDER BY 排序是按下面的順序取出數(shù)據(jù)的:
Absurdly Assured
absurd@assured.com

Absolutely Assured
absolutely@assured.com

Crazed Coder
crazy@coder.net

Loosely Fringe
loose@fringe.to

Lunatic Fringe
lune@fringe.to

Hands On
hands@yes.org


顯然ORDER BY 起了應(yīng)有的作用。在實(shí)際的表結(jié)構(gòu)下,Absurdly Assured 是最后的條目,但它排在檢索結(jié)果的最頂端。Hands On記錄排最后因?yàn)?O 在以上列表中排在字母表最后。顯然,Absolutely按照字母表最好排在Absurdly之前。為此,你需要采取第2級(jí)ORDER BY 排序標(biāo)準(zhǔn),參照第2列進(jìn)行排序:
SQL = "SELECT c_lastname, c_firstname, c_email FROM Customers ORDER BY
c_lastname, c_firstname"


其結(jié)果將首先按照c_lastname 列排序然后按照c_firstname 列排序。假如你的數(shù)據(jù)表包含的記錄比較多,仔細(xì)設(shè)計(jì)排序會(huì)令輸出結(jié)果編排更為合理。

投入使用
如果你同大多數(shù)程序員一樣喜歡自己動(dòng)手編代碼,沉湎于掌握新技術(shù)的狂熱之中。何不從ASP的冗長編碼中轉(zhuǎn)過頭來嘗試一下SQL編碼呢?下面我們將就ASP編程時(shí)常見的問題以及如何在ASP中高效地利用SQL語句做一番探討。

11. 記錄統(tǒng)計(jì)

確定數(shù)據(jù)庫內(nèi)有多少記錄,或者確定有多少記錄達(dá)到了某些標(biāo)準(zhǔn),這些用ASP完成并非難事。如果你采用了正確的游標(biāo)類型,你可以用RecordCount 屬性獲得記錄數(shù)當(dāng)然也可以用recordset。但是,有個(gè)更簡單的辦法,這就是在自己的SELECT語句中采用count(*) ,代碼如下所示:
SQL = "SELECT count(*) FROM Customers"

或者
SQL = "SELECT count(*) FROM Customers WHERE c_lastname LIKE 'A%'"

舉例說明,以下代碼將選出一些記錄以及這些記錄的總數(shù):
SQL = "SELECT c_firstname, c_lastname, count(*) FROM Customers WHERE c_lastname LIKE 'A%'"

但是你不能實(shí)現(xiàn)自己的目的。這里采用的“count”函數(shù)其實(shí)是一種集合函數(shù),意思是只返回單行信息:回答你提出的問題。對(duì)第1個(gè)SELECT 語句來說,問題是“在客戶表內(nèi)有多少條記錄?”查詢返回單一的值作為響應(yīng),因此它不能同你常規(guī)的查詢相組合。假如你希望得到其他數(shù)據(jù),你需要采用RecordCount。

集合函數(shù)除了“count”之外還包括AVG、MIN、MAX和SUM等。

12. 連接

任何熟悉SQL和關(guān)系數(shù)據(jù)庫的人都遇見過大量的連接類型。最簡單的說,連接(join)會(huì)把兩個(gè)表的內(nèi)容組合到一個(gè)虛擬表或者recordset內(nèi)。假如數(shù)據(jù)表有效地規(guī)一化,或許你會(huì)經(jīng)常從某一個(gè)表中選出特定的信息再從另一個(gè)表中選出關(guān)聯(lián)信息。這樣做就需要簡單的“同等連接(equijoin)”。

為了了解實(shí)際的連接操作,現(xiàn)在讓我們假設(shè)在一個(gè)數(shù)據(jù)庫內(nèi)存放了某類軟件的相關(guān)記錄。某個(gè)表(Software)包含了軟件產(chǎn)品的名稱、軟件的版本以及其他有關(guān)細(xì)節(jié):



另一個(gè)表(Releases)則存儲(chǔ)了軟件發(fā)布?xì)v史的信息,其中包括發(fā)布日期和發(fā)布狀態(tài)等(比如測(cè)試版、當(dāng)前版、過時(shí)等):


 

上表中還包含了一個(gè)列,內(nèi)容指向軟件表中采用的ID號(hào)。所以,通過這種索引軟件表的方式,你就知道發(fā)布表中software_ID 等于 2的軟件是Rome。

你采用連接組合信息,這樣就不需要在兩個(gè)表之間來回折騰了。不過,除了組合信息之外還可以通過連接把有關(guān)信息合并。這樣,只要發(fā)布表內(nèi)的software_ID 匹配軟件表內(nèi)的ID,你就把匹配信息一起放到一個(gè)記錄內(nèi)。

代碼如下:
SQL = "SELECT * FROM Software, Releases WHERE software.ID = releases.softwareID"

仔細(xì)分析以上的語句,首先注意到兩個(gè)表名列在了FROM的后面。再根據(jù)所采用的連接,今后你可能還會(huì)發(fā)現(xiàn)語法會(huì)有所變化(或者連接類型有變),但是以上的語法是最基本的,顯示了數(shù)據(jù)的聯(lián)合選擇方式。這里的WHERE 子句用來比較特定的ID值。在Software 表內(nèi),存在ID 列。同樣的,Releases 表內(nèi)則有個(gè)software_ID 列。為了明確你在WHERE 子句里要比較的值,你用表名作為前綴,后面還加上了一個(gè)點(diǎn)號(hào)(.)。

以下是連接選取數(shù)據(jù)之后的結(jié)果:


注意:在創(chuàng)建連接的時(shí)候要仔細(xì)考慮選出數(shù)據(jù)的列。以上代碼采用 * 通配符是為了讓讀者關(guān)注于SELECT 代碼行的其他部分。但是,正如你從上圖看到的那樣,你無法選出softwareID 列,因?yàn)檫@一列沒有作為recordset部分的增加值。它的作用就是為WHERE 子句所用。