1. 程式人生 > >VB6基本資料庫應用(七):多重條件搜尋

VB6基本資料庫應用(七):多重條件搜尋

同系列的第七篇,上一篇在:http://blog.csdn.net/jiluoxingren/article/details/48402835

多重條件搜尋

前文再續,書接上一回。很高興又能說出這句話了。

第五章講述了條件查詢。事實上SQL:Select語句的Where子句並不只是能接受一個條件。舉個實際應用的慄(例)子,如果有重名,那麼按姓名去查詢,就會出現多個結果,為了唯一確定一個人,我們還可以再提供需要查詢的人的手機號碼,一般而言這樣就唯一確定一個人了。

為此,我們在資料庫新增一個手機號碼欄位。開啟資料庫,然後在表的【設計檢視】中,再新增一個欄位,命名為【PhoneNo】。由於手機號碼也有11位的長度,所以還是設定資料型別為【雙精度型】,如下圖所示。


然後回到【資料表檢視】(在【設計檢視】和【資料表檢視】之間切換有更快捷的方法。就是在欄位名稱上面的那個Student那裡,單擊滑鼠右鍵,最下面會有選擇進入什麼檢視)。手工修改一下資料。修改好的資料如下所示:

 StudentID 

 StudentName 

 PhoneNo

 123456

 林則徐

 13888080088 

 562893

 葉劍英

 13920171101

 662356

 黃飛鴻

 13427103456

 785714

 黃飛鴻

 13978569013

電話號碼都是隨便亂編的。不過可以看到,有兩個“黃飛鴻”,不過學號和電話都不一樣。這樣只按第五章所說的,給出條件WHERE StudentName=’黃飛鴻’去查詢,結果就會有兩個了。

為了繼續講下去,還是必須要先講一下邏輯連線詞。什麼是邏輯連線詞呢?我們經常會這樣說話:“姓名是黃飛鴻,而且電話號碼是13978569013 的人”,這裡姓名和電話號碼是兩個條件,用“而且”兩個字連線起來,“而且”就是邏輯連線詞。

在SQL中,使用“與”(AND),“或”(OR),“非”(NOT)三個邏輯連線詞來連線多個條件。前面的“而且”相當於是“與”(AND)。

例如“姓名是黃飛鴻,而且電話號碼是13978569013 的人”,SQL語句可以寫成:

SELECT * FROM Student WHERE StudentName=’黃飛鴻’ AND PhoneNo=13978569013

邏輯連線詞的結合性

WHERE後面不僅能接兩個條件,還可以接多個條件,而且邏輯連線詞也不要求整一個語句都是用同一個連線詞。但是,如果有多個不同的連線詞,如何理解就會出現問題。例如:

SELECT * FROM Student WHERE StudentName=’黃飛鴻 AND PhoneNo=13978569013 OR PhoneNo=13888080088

為了突出一些,我讓每個條件顯示成不同的顏色。這條語句的條件翻譯成中文是這樣說的“學生名是黃飛鴻,且電話號碼是13978569013,或電話號碼是13888080088”。這樣問題來了,這句話可以有兩種理解:

1.      (學生名是黃飛鴻,且電話號碼是13978569013),或者是電話號碼是13888080088的任何一個人【不論名字】

2.      學生名是黃飛鴻,(且電話號碼是13978569013,或者是電話號碼是13888080088)【姓名一定要黃飛鴻,電話是這兩個之一就行,有其他的不要】

為了檢驗我們的理解那一種是正確的。啟動Access(圖示的版本是2013)。在【建立】選單單擊【查詢設計】,如下圖所示。


彈出來的一個對話方塊直接關掉,然後單擊一下介面左上角的SQL,就可以將查詢切換到【SQL檢視】


將上面的SQL語句複製貼上進去。注意,單引號要手工改一下,改成英文半形的單引號。文章這裡我雖然是用英文半形輸入,但是最後顯示的還是中文的單引號。中文符號是不行的!!


然後單擊左上角的執行之後結果就出來了,如下圖所示。


觀察Student表的資料可以知道,電話號碼是13888080088的人名叫林則徐。而查詢的結果中也包含了林則徐。這就證明第一種理解是正確。由此我們可以得出結論:

SQL中的多個邏輯連線詞總是從左往右運算的(左結合性)

所以(StudentName=’黃飛鴻 AND PhoneNo=13978569013)構成一個整體,然後再附加一個OR PhoneNo =13888080088。前面的給出了唯一的結果,即上圖的第二條記錄。然後PhoneNo =13888080088確定了第一條,名字是林則徐的記錄。

而且需要注意的是,結果記錄集的排序與查詢的條件無關。以後我會講到按照某個欄位的升序或降序進行排序。同樣也是在SQL:Select中完成的。

在SQL語句中,括號可以改變運算的順序,如果你真的要SQL是按照第二種理解執行的話,可以加上括號(英文半形括號):

SELECT * FROM Student WHERE StudentName=’黃飛鴻 AND (PhoneNo=13978569013 ORPhoneNo=13888080088)

執行的結果只有一條,就是上圖中的第二條記錄。

“非”(NOT)邏輯連線詞

這個邏輯連線詞出現的頻率極高。他可以搭配其他的邏輯連線詞使用,而且只對出現在其右邊的一個條件起作用。例如:

SELECT * FROM Student WHERE NOT StudentName='黃飛鴻' AND PhoneNo=13888080088

本來“非“(NOT)邏輯連線詞的加入,也會使語句在人理解的時候出現歧義,但是經過實驗,NOT只對右邊的一個條件起作用。實驗的方式也是跟上面一樣的,在Access裡執行一下語句看看結果即可。也就是說,上面這條語句的條件是“姓名不是黃飛鴻,並且電話號碼是13888080088的人”。所以這條語句的結果就是上圖的第一條記錄,林則徐的那條,因為13888080088是林則徐的電話號碼,而且姓名“林則徐”也滿足“姓名不是黃飛鴻”的條件。

同樣的,如果你希望讓NOT作用與多個條件,就要加上括號:

SELECT * FROM Student WHERE NOT (StudentName='黃飛鴻' AND PhoneNo=13888080088)

加上括號之後的結果是這樣的,如下圖所示。沒錯,全部都出來了。你能想明白為什麼嗎?


這也是一個需要注意的問題,在布林代數(數學)中,這樣的結果稱為德摩根定理:

1.      NOT( a AND b)      等價於  (NOT a) OR(NOT b)

2.      NOT( a OR b)        等價於  (NOT a) AND (NOT b)

這兩條結論稱為德摩根定理。其中的a,b可以是任意的條件。根據德摩根定理,上面的結果就很容易理解了

NOT (StudentName='黃飛鴻' AND PhoneNo=13888080088)

等價於

(NOT StudentName='黃飛鴻') OR (NOT PhoneNo=13888080088)

名字不是黃飛鴻的有林則徐,葉劍英。電話號碼不是13888080088(對應名字是林則徐)的有兩個黃飛鴻,還有葉劍英。中間用OR連線,那當然是全都出來了。其實直接理解也是可以的,名字是黃飛鴻,電話號碼是13888080088的人是沒有的,所以結果是空的,最後NOT一下,空的相反就是全部了。

所以,如果要給NOT加括號,那就要想清楚了。

接著,我們來寫一下程式碼檢查一下,介面當然是要修改一下的,增加一個ListBox來顯示電話號碼,修改好的介面如下所示。

由於目前我用來用去都是SQL:Select語句,所以我不說,大家也應該知道怎麼做了吧。新的測試只需要將RecordSet物件的Open方法的第一個引數換成相應的SQL語句即可。不過因為改變了介面,所以我還是貼出全部的程式碼以供參考。這份程式碼只檢驗了語句SELECT* FROM Student WHERE StudentName=’黃飛鴻’ AND PhoneNo=13978569013 OR PhoneNo =13888080088的結果。

VB程式碼開始:

Dim Cnn As ADODB.Connection

Dim rec As ADODB.Recordset

Private Sub Form_Load()

'建立新的Connection物件

Set Cnn= New ADODB.Connection

'注意要記住該資料庫目錄為你資料庫檔案當前的位置

Cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\Sample.mdb;PersistSecurity Info=False"

'建立新的Recordset物件

Set rec= New ADODB.Recordset

'開啟student表的全部欄位的全部內容

'adOpenKeyset, adLockOptimistic。鍵集遊標和開放式鎖。

'單純為了讀取資料應該使用只進遊標和只讀鎖。

'但是為了方便就統一使用鍵集遊標和開放式鎖了

'詳細參見第十章

rec.Open "SELECT * FROM Student WHERE StudentName='黃飛鴻' AND PhoneNo=13978569013 OR  PhoneNo =13888080088", Cnn, adOpenKeyset, adLockOptimistic

'資料的提取

Do Until rec.EOF = True

List1.AddItem rec.Fields("StudentID").Value

'Fields物件,括號裡的是索引(Index),索引填寫的內容為欄位的名稱

'Item屬性是Fields物件的預設屬性,他的一個引數就是Index

'Fields("Student")表示一個Field物件

'Fields("Student")等價於

'rec.Fields.Item("Student")

'rec.Fields!("Student")

'!表示預設屬性

List2.AddItem rec.Fields("StudentName").Value

List3.AddItem rec.Fields("PhoneNo").Value

'移動下一條記錄為當前記錄

rec.MoveNext

Loop

End Sub

VB程式碼結束

在這裡羅列出這一章所給出的SQL語句,讀者自己把它們放到Open方法的第一個引數中,執行一下程式,結果跟上面再Access中執行SQL的結果是一樣的,就不再截圖了。

本章相關的SQL語句:

1.      SELECT * FROM Student WHERE StudentName=’黃飛鴻’ AND PhoneNo=13978569013 OR PhoneNo =13888080088

2.      SELECT * FROM Student WHERE StudentName=’黃飛鴻’ AND (PhoneNo=13978569013 OR PhoneNo =13888080088)

3.      SELECT * FROM Student WHERE NOT StudentName='黃飛鴻' AND PhoneNo=13888080088

4.      SELECT * FROM Student WHERE NOT (StudentName='黃飛鴻' AND PhoneNo=13888080088)

那麼長時間不寫教程,開始的時候還真找不到感覺,不知道自己要說什麼,怎麼說,真是慚愧。感覺到後面才漸漸回來了。才發現原來多重條件查詢自己能說出那麼多東西,於是把第五章最後修改了一下,這一章標題也修改了一下,只說多重條件查詢。模糊查詢和基於範圍的查詢之後再講。

下一章,我將來講述模糊搜尋與基於範圍的搜尋,敬請期待。本套教程未完,待續。