1. SELECT 語句
在SQL的世界裡,最最基礎的操作就是SELECT 語句了。在資料庫工具下直接採用SQL的時候很多人都會熟悉下面的操作:
SELECT what
FROM whichTable
WHERE criteria
執行以上語句就會建立一個存放其結果的查詢。
而在ASP分頁檔上,你也可以採用以上的一般文法,不過情況稍微不同,ASP編程的時候,SELECT 語句的內容要作為字串賦給一個變數: SQL = "SELECT what FROM whichTable WHERE criteria"
明白了ASP下SQL“說話”的方式,接下來如法炮製即可,只要滿足你的需要,傳統的SQL查詢模式和條件查詢都能派用場。
舉例說明,不妨假設你的資料庫內有個資料表,名字是Products ,現在你想取出這個表裡的全部記錄。然後你就編寫了下面的代碼:
SQL ="SELECT * FROM Products"
以上代碼——SQL語句的作用就是取出表內的全部資料——執行後將會選出資料表內的全部記錄。不過,要是只想從表內取出某個特定列,比如p_name。那就不能用 * 萬用字元了,這裡得鍵入具體某列的名字,代碼如下:
SQL ="SELECT p_name FROM Products"
執行以上查詢之後Products 表內、p_name 列的內容就會全被選取出來。
2. 用WHERE子句設定查詢條件
有的時候取出全部資料庫記錄也許正好滿足你的要求,不過,在大多數情況下我們通常只需得到部分記錄。這樣一來該如何設計查詢呢?當然會更費點腦筋了,何況本文也存心不想讓你去用那個什麼勞什子的recordset。
舉個例子,假如你只打算取出p_name 記錄,而且這些記錄的名字必須以字母w打頭,那麼你就要用到下面的WHERE 子句了:
SQL ="SELECT p_name FROM Products WHERE p_name LIKE 'W%'"
WHERE 關鍵詞的後面跟著用來過濾資料的條件,有了這些條件的協助,只有滿足一定標準的資料才會被查詢出來。在以上的例子裡,查詢的結果只會得到名字以w 打頭的p_name 記錄。
以上例子中,百分比符號(%)的含義是指示查詢返回所有w 字母打頭而且後面是任何資料甚至沒有資料的記錄條目。所以,在執行以上查詢的時候, west 和 willow 就會從Products 表內被選取出來並存放在查詢裡。
就像你看到的那樣,只要仔細地設計SELECT 語句,你就可以限制recordset 中返回的資訊量,多琢磨琢磨總能滿足你的要求。
這些啊還不過是掌握SQL用途剛起步。為了協助你逐步掌握複雜的SELECT 語句用法,下面就讓我們再來看一下關鍵的標準術語:比較子,這些玩意都是你在構築自己的SELECT 字串來獲得特定資料時要經常用到的。
WHERE子句基礎
在開始建立WHERE 子句的時候,最簡單的方式是採用標準的比較符號,它們是 < 、 <= 、 > 、 >= 、<> 和 =。顯然,你很快就能明白以下代碼的含義和具體運行結果:
SELECT * FROM Products WHERE p_price >= 199.95
SELECT * FROM Products WHERE p_price <> 19.95
SELECT * FROM Products WHERE p_version = '4'
注意: 這裡你會注意到,最後一個例句中的數字4周圍加了單引號。原因是這樣的,在這個例子中的 '4' 是文本類型而非數字類型。因為你會把 SELECT 語句放到引號中來把它作為一個值賦給變數,所以你也可以在語句中採用引號。
比較子
比較子指定從表內取出資料的內容約制。你可以用它們來建立過濾器以便縮小recordset的範圍,促使其只儲存給定任務下你關心的資訊。
3. LIKE 、 NOT LIKE和 BETWEEN
你已經在上面取出w打頭記錄的例子中看到了LIKE的用法。LIKE判定詞是一個非常有用的符號。不過,在很多情況下用了它可能會帶給你太多的資料,所以在用到它之前最好先開動腦筋多想想自己到底想獲得什麼資料。假設你想取出5位元字的SKU號碼,而且其開頭是1結尾是5,那麼你可以用下劃符(_)代替%符號:
SQL = "SELECT * FROM Products WHERE p_sku LIKE '1___5'"
下劃符表示任意一個字元。所以在輸入“1 _ _ _ 5”的情況下,你的搜尋就會限制在滿足特定模式的5位元範圍內了。
假如你想反其道而行之,要找出所有不匹配“1_ _ _ 5”模式的SKU條目。那麼你只需要在剛才語句例子中的LIKE前面加上NOT就可以了。
BETWEEN
假設你想取出一定範圍內的資料,而且你事Crowdsourced Security Testing道範圍的起點和終點,那麼你不妨採用BETWEEN 判斷詞。現在就讓我們假設你想選取給定表內範圍在 1和 10之間的記錄。你可以如下使用BETWEEN:
…WHERE ID BETWEEN 1 AND 10
或者你也可以採用已經熟悉的數學判斷字句:
…WHERE ID >= 1 AND ID >= 10
4. 聯合語句
我們到目前為止所談到的SQL語句相對較為簡單,如果再能通過標準的recordset迴圈查詢,那麼這些語句也能滿足一些更複雜的要求。不過,何必非要拘泥在淺嘗則止的基礎水準之上呢?你完全可以再增加其他一些符號,比如AND、 OR和NOT來完成更強大的功能。
以下面的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知識,以上的例子也不難解釋,不過上面的語句並沒有很明白地讓你看清條件字句是如何膠合在單一SQL語句中的。
多行語句
在SQL語句不好懂的情況下,你不妨把整個語句分解為多行代碼,然後在現有變數基礎上逐步增加查詢語句的各個組成部分並把它存在同一變數內:
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"
整句照上面分解之後顯然好讀多了!在進行調試的時候,你或許更樂於多敲幾個字元把程式改得更好讀些。不過你可要記住了,在封閉引號之前或者在開啟引號之後你需要增加空格,這樣才能保證字串串連起來的時候你沒有把幾個詞湊到了一塊。
5. 開始執行
在學會了SELECT語句的構造和用途之後你就該學習如何使用它了。在你所掌握的資料庫工具下,這可能意味著你得按下某個寫著“執行”字樣的按鈕。在ASP網頁上,可以立即執行SQL語句也可以當作預存程序調用。
一旦建立了SQL 陳述式,你還得設法訪問其查詢結果。顯然,這裡的關鍵就是ASP recordset。在使用非SQL的recordset時,建立recordset的代碼通常如下所示:
Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open "customers", objConn, 0, 1, 2
如果你對ASP比較熟悉以上的代碼對你可就不陌生了,你應該知道“customers”表示你開啟資料庫內一個資料表的名字。
開啟recordset
為了充分利用你更為熟悉的SQL技能,你需要調整常規ASP網頁上最常採用的recordset:
Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open SQL, objConn, 0, 1, 2
這裡唯一的修改就是在objRec.Open,之後用包含SQL語句的變數代替了要查詢的資料表的名稱。
這種方法的優點之一是你可以指定遊標類型(如以上0, 1 ,2 所示)。
執行SQL
你可以用緊湊的一行代碼執行SQL語句來建立recordset。以下是文法:
Dim objRec
set objRec = objConn.Execute(SQL)
在上例中,你所看到的SQL是你存放自己SQL SELECT 語句的變數。該程式碼“運行”SQL語句(或者說對資料庫進行查詢),選取資料並把資料存放在recordset 內,在上例中就是變數objRec。這種方法的主要缺點是你不能選擇自己想採用的遊標類型。相反,recordset總是用前向遊標開啟。
因為遊標的緣故,你或許打算熟悉兩種建立recordset的方法。直接執行查詢節省了鍵入字元所消耗的時間,但那樣的話你就得採用預設的遊標了,這樣有可能遭遇經常不能正常啟動並執行毛病。不管你具體採用哪種辦法,兩者之間的最大的差別也不外乎代碼精練與否。在不考慮你取得什麼欄位、你的標準是什麼的前提下,也不管你如何儲存資料,採用SQL式的recordset 在體積上會比ASP上開啟的標準recordset 要小得多,更別提操作起來的簡易性了。畢竟,通過過濾資料,你消除了耗費時間的if-then 測試和可能用到的迴圈。
編寫測試用SQL
這裡有個技巧,許多專業ASP程式員習慣在測試網頁的時候“編寫”自己的SQL語句。這樣做可以協助你調試代碼,因為你可以從中看到傳遞給伺服器執行的字串。而你要做的無非是增加Response.WriteyourVariable 在螢幕上顯示有關資訊。在你把和SQL有關的問題提交給ASP討論群組的時候你就應該附上這些資訊。
6. 儲存查詢
當你的查詢相對簡單的時候,每次從頭開始建立SQL語句也不費什麼工夫,不過,複雜的查詢就不同了,每次都從頭來會產生很多開發錯誤。因此,一旦讓SQL順利地運行起來,你最好把它們存起來,在需要時再調用它們。這樣,哪怕是一個簡單查詢你都能隨時用上儲存的查詢語句了。
假設你每周都要給團隊做一次報告,指出目前存在的業務支援問題,這些資料需要從你的資料庫中選取,而且要按照日期選擇記錄,同時根據你所在團隊所採用的支援問題的類別排序。一旦你設計了這一查詢,你何必以後每周都重新編寫一次呢?不要在你的HTML頁面上建立查詢,你應該用你的資料庫工具建立查詢並且儲存它。
然後你可以採用ActiveCommand 屬性把查詢插入到你的ASP網頁。頭一兩回你可能會覺得沒啥意思,其實也就幾行代碼而已:
Set objSQ = Server.CreateObject ("ADODB.Command")
objSQ.ActiveConnection = "databaseName"
objSQ.CommandText = "storedQueryName"
objSQ.CommandType = adCmdStoredProc
set objRec = objSQ.Execute
注意,採用adCmdStoredProc 表示你已經在頁面上包含了adovbs.inc 檔案。該檔案定義了你可以按照名字而非數字進行訪問的Access常數。只需要在頁面上包含該檔案即可(<!--#INCLUDE -->),然後你就可以用adCmdStoredProc 這類名字了。這樣,將來你再看到的時候更容易理解以上被儲存的查詢到底是個什麼意思。
7. ORDER BY
從Access資料庫中選取記錄有件最令人喪氣的事情,它們是以怎樣的順序輸入到資料庫內就按照怎樣的順序出來。就算你在Access環境內採用Sort By來改變記錄視圖,資料表內的記錄順序也並沒有發生改變。
如果你正在使用ASPrecordset在網頁上寫出記錄,那麼你或許知道亂紛紛的順序是多令人痛苦的事。但是你可能不得不經常得面對這一問題,因為並不存在什麼簡單方便的解決方案。好在ORDER BY 可以簡化這一難題。
為了對你的結果排序,只要在SELECT語句末尾加上ORDER BY,然後指定你需要排序的參照列即可。因此,如果你想要根據顧客的姓氏對Customers表排序,那麼你可以編寫如下的查詢語句:
SQL = "SELECT c_lastname, c_firstname, c_email FROM Customers ORDER BY c_lastname"
這樣,只要你建立了recordset而且開始把結果寫到螢幕上,你就會看見資料按照字母順序排列起來了。
8. 記錄統計
確定資料庫內有多少記錄,或者確定有多少記錄達到了某些標準,這些用ASP完成並非難事。如果你採用了正確的遊標類型,你可以用RecordCount 屬性獲得記錄數當然也可以用recordset。但是,有個更簡單的辦法,這就是在自己的SELECT語句中採用count(*) ,代碼如下所示:
SQL = "SELECT count(*) FROM Customers"
或者
SQL = "SELECT count(*) FROM Customers WHERE c_lastname LIKE 'A%'"
舉例說明,以下代碼將選出一些記錄以及這些記錄的總數:
SQL = "SELECT c_firstname, c_lastname, count(*) FROM Customers WHERE c_lastname LIKE 'A%'"
但是你不能實現自己的目的。這裡採用的“count”函數其實是一種集合函數,意思是只返回單行資訊:回答你提出的問題。對第1個SELECT 語句來說,問題是“在客戶表內有多少條記錄?”查詢返回單一的值作為響應,因此它不能同你常規的查詢相組合。假如你希望得到其他資料,你需要採用RecordCount。
集合函數除了“count”之外還包括AVG、MIN、MAX和SUM等。
9. 串連
任何熟悉SQL和關聯式資料庫的人都遇見過大量的連線類型。最簡單的說,串連(join)會把兩個表的內容組合到一個虛擬表或者recordset內。假如資料表有效地規一化,或許你會經常從某一個表中選出特定的資訊再從另一個表中選出關聯資訊。這樣做就需要簡單的“同等串連(equijoin)”。