@Andriy M獲獎。正如他正確猜測的那樣,SQL Server處理WHERE子句,MS Access處理SELECT子句。
通常這種悄無聲息,但的Transact-SQL LEN()
修剪尾隨空白之前計數的字符,而VBA Len()
功能不。請閱讀下面的完整說明。
我跑的SQL Server Profiler來看看有什麼MS Access已實際發送幕後,這裏就是我的了:
SELECT "dbo"."MyTable"."MyTableID"
FROM "dbo"."MyTable"
WHERE NOT(({fn length("MyField")}= 10))
上面的查詢返回的所有的匹配記錄的主鍵標準Len(MyField) <> 10
。 {fn length()}
是ODBC Canonical Function。
MS SQL Server使用自己的Len()
function實現了{fn length()}
規範函數。正如@Sir Crispalot在他的回答中指出的那樣,Transact-SQL Len函數修剪尾隨空格。所以在MS SQL Server中,Len('M1023-324 ') = 9
。當然,在VBA中,Len("M1023-324 ") = 10
。
如果你仔細看看上面的查詢,你會發現它實際上並沒有返回我在原來的SELECT語句中請求的字段。相反,它只是返回足夠的信息(即主鍵字段)爲MS Access來請求完整的記錄,因爲它需要它們。
這是出於性能原因。如果我的查詢返回了30,000行並且每行有三十個字段,如果我在數據表中一次只顯示10行,那麼從SQL Server中獲取所有信息是沒有意義的。所以Access所做的就是獲取所有這些主鍵,然後一次從SQL Server請求單個記錄。此外,它實際上在SQL Server中創建臨時存儲過程,以執行它以返回這些單獨的行。我現在正在轉向脫離主題,但如果您有機會使用SQL Server Profiler,那麼值得做一些實驗來了解Access在幕後實際執行的操作。
無論如何,在SELECT子句中,MS Access只從SQL Server請求字段本身的內容。也就是說,它要求MyField
而不是'#' & MyField & '#'
。這也意味着它要求MyField
而不是Len(MyField)
。
最終的結果是SQL Server執行篩選操作(WHERE子句)的計算,MS Access執行顯示操作(SELECT子句)的計算。而由於Len()
功能在每個環境的行爲稍有不同,我們最終有一些什麼會考慮一個非常混亂的結果:
10 <> 10
但它使我感覺良好。
從您的提示下面,我懷疑這可能與ODBC設置或怪癖有關。 – HK1