簡體   English   中英

MS Access中SQL查詢的奇怪結果

[英]Odd Results from an SQL query in MS Access

好吧,這是我正在運行的MS Access數據庫中的一個奇怪數據。

我有一個SQL查詢:

SELECT * 
FROM [Service Schedule]
WHERE ID=2 
  AND Volume <= 3000 
  AND Term='Monthly'
  AND special = 'Regular'
ORDER BY volume

將其放入查詢生成器的SQL視圖中時,我得到2條記錄,一條記錄的卷為0,一條記錄的卷為3000。

當我使用此代碼時:

sSQL = "SELECT * FROM [Service Schedule] WHERE ID=2 AND Volume <= 3000 AND Term='Monthly' and special = 'Regular' ORDER BY volume"            
Set rsServiceSched = CurrentDb.OpenRecordset(sSQL, dbOpenDynaset, dbSeeChanges)

**要查看我從代碼查詢中得到的內容,我使用Debug.Print輸出recordcount和卷。

我只得到1條記錄,一條記錄的數量為0。

這是真的很奇怪的地方...

當我將Volume <= 3000更改為Volume <3000時,我得到一條記錄(volume = 0)

當我將音量<= 3000更改為音量= 3000時,我得到一條記錄(音量= 3000)

有人發現我在做什么嗎?

題外話:DAO記錄集記錄數的討論

直到.MoveLast之后,才能保證DAO記錄集的記錄計數准確,但是如果記錄集返回了任何記錄,則.RecordCount將為1或更大。

請注意,表類型記錄集將立即返回准確的.RecordCount,而沒有.MoveLast,但是請記住,您無法在鏈接表上打開表類型記錄集。 另外,請小心,不要假定您正在獲取所需的記錄集類型,除非您已明確指定它。 雖然dbOpenTable是默認的記錄集類型,但是如果不能將表或SQL字符串作為表類型的記錄集打開,則它將變為打開動態集。 因此,您可以認為您正在使用它來打開表類型記錄集,因為table-type是默認值,並且您已經傳遞了表名:

  Set rs = CurrentDB.OpenRecordset("MyTable")

但是您必須記住,僅僅因為您向它傳遞了一個表,所以它不一定會打開一個表類型的記錄集,並且recordcount不一定是准確的。 如果您確實要確定要打開表類型的記錄集,則需要明確指定:

  Set rs = CurrentDB.OpenRecordset("MyTable", dbOpenTable)

如果“ MyTable”是鏈接表,則將引發錯誤。 如果混合使用鏈接表和本地表,則必須使用兩種不同的方法來獲取表類型的記錄集。 否則(例如,如果您未指定記錄集類型,並在可能的情況下將其設置為表類型,而在未指定時設置為動態集),則需要知道何時需要.MoveLast才能獲取准確的.RecordCount。 如果您真的想在這種情況下提高效率,請測試記錄集的.Type:

  Set rs = CurrentDB.OpenRecordset("MyTable")
  If rs.Type = dbOpenDynaset Then
     rs.MoveLast
  End If

那時,無論記錄集是以表類型還是動態集打開,您都將具有一個准確的.RecordCount屬性。

但是請記住,很少需要使用完整的記錄集來獲取記錄計數。 通常,您只檢查.RecordCount即可查看記錄集是否返回了任何記錄,在這種情況下,您不需要准確的計數。

同樣,如果您要遍歷完整的記錄集,最終將獲得准確的RecordCount。 也就是說,這樣做是沒有意義的:

  Set rs = CurrentDB.OpenRecordset("MyTable")
  rs.MoveLast
  If rs.RecordCount > 0 Then
     .MoveFirst
     Do Until rs.EOF
       [something or other]
       .MoveNext
     Loop
  End If
  Debug.Print rs.RecordCount

在那種情況下,.MoveLast是完全不需要的,因為您無需知道代碼中該點的確切計數。

另外,請記住,在某些情況下,您確實確實需要知道確切的.RecordCount,僅使用內置的Access DCount()函數或執行以下操作可能會更有效:

  Dim lngRecordCount As Long
  lngRecordCount = CurrentDB.OpenRecordset("SELECT COUNT(*) FROM MyTable")(0)

要么:

  lngRecordCount = DBEngine.OpenDatabase(Mid(CurrentDB.TableDefs("MyTable").Connect, 11)).TableDefs("MyTable").RecordCount

有各種各樣有效的快捷方式可以獲取准確的RecordCount,而無需強制記錄集指針移動到最后一條記錄。

順便說一句,純Table-Type記錄的RecordCount准確的原因之一是因為不必進行計算-Jet / ACE將RecordCount屬性作為其常規操作的一部分進行維護。

題外話:ADO記錄集的Recordcount的討論

通過@onedaywhen

對於ADO記錄集, RecordCount屬性將始終是最終值。 也就是說,與DAO不同,如果您檢查其值,則以后將無法更改。 導航EOF不會以任何方式影響ADO的RecordCount值。

即使異步獲取記錄(DAO記錄集不明確支持),也是如此:也就是說,即使記錄集尚未滿, RecordCount屬性仍會反映最終值(而不是到目前為止獲取的記錄數) DAO)。

CursorLocationCursorType某些組合將使RecordCount始終為-1,這意味着不支持該屬性。 但是,再次,它將保持恆定,即如果最初為-1,那么它將始終為-1。

不支持RecordCount的Access數據庫引擎的適用組合是adOpenForwardOnlyadOpenDynamic但僅在使用服務器端光標位置時才適用。 (請注意,Access數據庫引擎實際上並不支持動態游標: adOpenDynamic過載了,以便用戶向記錄引擎的Source是動態SQL代碼的引擎提供優化“提示”)。

請注意,設置記錄集的Filter屬性將更改RecordCount以反映應用過濾器后的記錄數。

我不確定您要為該表的PK值做什么,但是當您說:“ ID = 2”時,這聽起來像是我的魚,因為我總是使用代理鍵(從不自然),而ID始終是PK。 由於您沒有加入任何表,因此這告訴我您應該始終從結果中期待一行/元組。

如果ID不是您的PK,您可以通過評論讓我知道嗎?

也許您需要使用以下方法迭代結果集:Set.MoveNext

聽起來您希望“查看”所有記錄,但是我認為您只是在檢索第一個記錄。 我說這是因為您看到的是每種情況的第一筆記錄。 您可能需要移動到記錄集中的下一條記錄才能查看下一條。

rsServiceSched.MoveNext

您可能沒有遍歷結果集。 rsServiceSched僅指向第一個記錄,該記錄將是最小記錄(您的order by子句的購買)。 現在您需要對此進行處理,然后進入下一個記錄

這個例子可能對您有幫助...

這是DAO,您需要移動到最后以獲取完整的記錄數; 否則,如果記錄存在,您將只得到1,否則就得到0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM