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)

 

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

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


下一章:模糊搜索與基於範圍的搜索 http://blog.csdn.net/jiluoxingren/article/details/48474545

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章