到SQL Server的Access開發人員面臨著很多困難,然而最為棘手的問題是對動態SQL的處理。在Access中,將控制項的行指定為一個字串是相當普通的現象。例如,表單上包含著很多的選取器(SalesGroup,State/Province/Canton,Beginning Date以及Ending Date等等),Access開發人員一般都會檢查這些控制項以查看哪些為Null,然後編寫SQL語句以刪除這些Null值。
通過這種方法串連到SQL Server具有以下幾點的缺點:
所有的處理都在用戶端完成,而不是在伺服器中完成。
解析這些控制項和處理SQLq語句的代碼顯得拖遝冗長。
這一方法容易導致SQL 混入攻擊(injection attacks)。
渴望擴充到SQL Server的Access開發人員必須解決兩個方面的問題:
1. 識別所有非基於名稱查詢的記錄和行的資料來源。
2. 使用名稱查詢替代所有的查詢。
對於動態地處理查詢,可以以如下所示的代碼處理:
SELECT *
FROM SomeTables
WHERE ColumnOfInterest = Forms("myForm").ControlOfInterest
AND Column2OfInterest = Forms("myForm").Control2OfInterest
為了簡單起見,我們假設Access表單上只包含兩個控制項。Access方法將在代碼中解析控制項的值,然後通過使用非零值的方法處理每一動態SQL查詢。
這是一種沒有嚮導的方式。你所需要的是一個儲存程式,這一儲存程式被參數化以接收來自表單上控制項的所有資料。例如,假設以上給定的兩個控制項,儲存程式被自身的資料觸發,如果數值為Null,儲存程式就會“智能化地”執行。
這裡是實現這一過程的一個簡單技巧:
SELECT *
FROM SomeTables
WHERE ColumnOfInterest = 12345 OR ColumnOfInterest is NULL
對於Access而言,你調用的是儲存程式,然後傳遞所有相關控制項的數值,而不管這些數值是否為Null:
EXEC mySproc Value1, Value2,. . .ValueN
然後,儲存程式如上所示地處理這些Null值。可以想象到,儲存程式選擇使用者提供的值,然後傳遞一個值(比如12345)並返回到一行,接著OR語句被調用。由於參數為Null,返回所有行的值。
這裡是說明這一技巧使用過程的Northwind資料庫範例。在這一範例中,在特定日期被傳遞之前,我們列舉了所有的定單:
CREATE PROCEDURE dbo.OrdersListSproc1
(@OrderDateDateTime)
AS SELECT dbo.Orders.*
FROM dbo.Orders
WHERE (OrderDate < CONVERT(DATETIME, '1996-08-01 00:00:00', 102))
OR (@OrderDate IS NULL)
雖然儲存程式無法總是以這種方式取代動態SQL,但這種方法通常可以提高程式的效能。
本文作者:Arthur Fuller從事資料庫應用程式開發已達20多年之久,他精通Access ADPs,Microsoft SQL 2000,MySQL,以及.NET。