3

我正在使用鏈接到SQL Server 2012數據庫後端的Access 2010前端。使用傳遞參數訪問調用存儲過程

在Access前端中,我有一個通用搜索屏幕,由一個文本框組成,其結果顯示在列表框中。我希望文本框能夠搜索多個也需要通配符的字段。

所以,我的存儲過程是這樣的:

ALTER PROCEDURE [dbo].[SalesGeneralSearch] 
    @Search nvarchar(50) = '' 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT 
     tblJobHead.JobNum, 
     tblCustomer.LastName, 
     tblCustomer.M3DealerCode, 
     tblCustomer.TradeRef, 
     tblCustomer.Postcode, 
     tblJobHead.[Item Number], 
     tblJobHead.Description, 
     tblStatus.[Desc] AS Status 
    FROM 
     tblCustomer 
    INNER JOIN 
     (tblJobHead 
    INNER JOIN 
     tblStatus ON tblJobHead.Status = tblStatus.StatusID) ON tblCustomer.RepNum = tblJobHead.[Rep Num] 
    WHERE 
     (((tblJobHead.JobNum) Like '%'+ @Search + '%')) 
     OR (((tblCustomer.LastName) Like '%' + @Search + '%')) 
     OR (((tblCustomer.M3DealerCode) Like '%' + @Search + '%')) 
     OR (((tblCustomer.TradeRef) Like '%' + @Search + '%')) 
     OR (((tblCustomer.Postcode) Like '%' + @Search + '%')) 
    ORDER BY 
     tblJobHead.JobNum DESC; 
END 

好了,現在回訪問。在搜索屏幕上,我有用戶輸入的文本框,點擊搜索按鈕和結果列表框。按鈕我有下面的代碼的Click事件:

Dim rs As ADODB.Recordset 
Dim cn As ADODB.Connection 
Dim cmd As ADODB.Command 
Dim prm As ADODB.Parameter 
Dim adString As Variant 


Set cn = New ADODB.Connection 

cn.ConnectionString = "DRIVER=SQL Server;SERVER=XXX;Database=XXX;Trusted_Connection=YES;" 
cn.Open 

    Set cmd = New ADODB.Command 
    With cmd 
     .ActiveConnection = cn 
     .CommandText = "dbo.SalesGeneralSearch" 
     .CommandType = adCmdStoredProc 
     Set prm = .CreateParameter("@Search", adString, adParamInput) 
     .Parameters.Append prm 
     cmd.Execute 
     prm.Value = Me.Search.Text 
    End With 

    Set rs = New ADODB.Recordset 
    With rs 
     .CursorLocation = adUseClient 
     .CursorType = adOpenStatic 
     .LockType = adLockReadOnly 
     .Open cmd 
    End With 
    Set Me!lstJobQuickSearch.Recordset = rs 
    Me.lstJobQuickSearch.Requery 
Set prm = Nothing 
Set cmd = Nothing 

然而,當我點擊搜索按鈕,我不斷收到以下錯誤:

運行時錯誤3708參數對象定義不正確

和它突出

.Parameters.Append prm 

的lstJobQuickSearch的行源是穿過查詢作爲使用以下公:

SELECT tblJobHead.JobNum, tblCustomer.LastName, tblCustomer.M3DealerCode, tblCustomer.TradeRef, tblCustomer.Postcode, tblJobHead.[Item Number], tblJobHead.Description, tblJobHead.FN, tblStatus.[Desc] AS Status 
FROM tblCustomer INNER JOIN (tblJobHead INNER JOIN tblStatus ON tblJobHead.Status = tblStatus.StatusID) ON tblCustomer.RepNum = tblJobHead.[Rep Num] 
ORDER BY tblJobHead.JobNum DESC; 

我哪裏出錯了?任何幫助將不勝感激。

因爲我只是想返回值,使用傳遞查詢和代碼參數更有效嗎?我不知道,我一直工作在這天: - (

問候,

邁克爾

+1

嘗試'設置prm = .CreateParameter(「@ Search」,adVarWChar,adParamInput,50)' – 2014-10-03 10:32:52

+0

已經工作了!非常感謝。出於興趣 - 究竟是什麼導致了這個問題? – Michael 2014-10-03 11:42:55

回答

2

的問題是,存儲過程聲明輸入參數爲nvarchar(50),但在VBA中ADODB.Parameter正在使用adString並沒有長度定義問題:對SQL服務器映射到adVarWChar

  1. nvarchar在ADO
  2. 個字符串參數幾乎總是需要有一個定義的(最大)長度

因此,解決方法是在參數聲明更改爲

Set prm = .CreateParameter("@Search", adVarWChar, adParamInput, 50) 
+0

對,感謝您的解釋,現在有道理。再次感謝。 – Michael 2014-10-03 11:54:01

3

我會用一個DAO通不過。假設你救了一通,雖然查詢,那麼這段代碼將工作:

With CurrentDb.QueryDefs("qPass") 
    .SQL = "exec SalesGeneralSearch " & strSearch 
    Set Me.MyListBox.RowSource = .OpenRecordset 
    End If 

真的沒有必要張貼代碼僅作爲通過不誠實的開發商時,一個簡單的2線盜竊公司的計費時間,這些大規模敲敲罷了按照上述就足夠了。

+0

我認爲將使用正確參數化的ADO方法歸類爲「不誠實開發人員盜用公司計費小時」是相當不公平的。至少你的示例需要做一些努力來限定輸入參數,以防它包含一個或多個空格,然後它需要轉義用戶輸入中的任何分隔符以避免動態SQL中固有的潛在語法錯誤。有時我們需要在「快速做」和「做對」之間做出選擇。 – 2014-10-05 21:32:55

+0

這是一個公平點。沒有抱怨,如果解決方案是10,15甚至25 LOC。該示例已超過30 LOC。我的例子有4.所以確定包括文檔,包括增加可讀性的空白空間等等。所有這些都是很好的,我會建議少用代碼總是更好。我更喜歡額外的代碼行來提高可讀性和維護性。從4 LOC跳到超過30行代碼?那麼是的,一些合法的問題出現並開始需要被問到。 9X的這種比率對於我的15LOC來說意味着一些將會發布135並且這樣的比率值得仔細研究。 – 2014-10-06 23:40:35

+1

我只在3個月前開始編碼 - 給我休息一下! – Michael 2014-10-08 18:40:45