2012-04-27 20 views
17

Tôi có excel VBA kịch bản:
VBA, ADO.Connection và truy vấn các thông số

Set cоnn = CreateObject("ADODB.Connection") 
conn.Open "report" 
Set rs = conn.Execute("select * from table") 

Script hoạt động tốt, nhưng tôi muốn thêm tham số để nó. Ví dụ: "where (parentid = myparam)", trong đó myparam được giải quyết bên ngoài chuỗi truy vấn. Tôi làm nó như thế nào?

Tất nhiên tôi có thể sửa đổi chuỗi truy vấn, nhưng tôi nghĩ nó không phải là rất khôn ngoan.

Trả lời

25

Bạn cần sử dụng đối tượng ADODB.Command mà bạn có thể thêm tham số vào. Về cơ bản, điều này trông giống như

Sub adotest() 

    Dim Cn As ADODB.Connection 
    Dim Cm As ADODB.Command 
    Dim Pm As ADODB.Parameter 
    Dim Rs as ADODB.Recordset 

    Set Cn = New ADODB.Connection 
    Cn.Open "mystring" 
    Set Cm = New ADODB.Command 
    With Cm 
     .ActiveConnection = Cn 
     .CommandText = "SELECT * FROM table WHERE parentid=?;" 
     .CommandType = adCmdText 

     Set Pm = .CreateParameter("parentid", adNumeric, adParamInput) 
     Pm.Value = 1 

     .Parameters.Append Pm 

     Set Rs = .Execute 
    End With 

End Sub 

Dấu hỏi trong CommandText là trình giữ chỗ cho tham số. Tôi tin rằng, nhưng tôi không tích cực, thứ tự mà bạn Nối các tham số phải khớp với thứ tự của các dấu hỏi (khi bạn có nhiều hơn một câu hỏi). Đừng để bị lừa rằng tham số được đặt tên là "parentid" bởi vì tôi không nghĩ rằng ADO quan tâm đến tên khác ngoài việc nhận dạng.

+1

Cảm ơn bạn, bạn viết mã workfs tốt :) – Alexey

+2

Tôi tin rằng bạn đúng về thứ tự tham số. Điều này dẫn tôi lên khi tôi đến từ C#. Net và sau đó mã hóa VBScript. – Coops

+0

Hoặc bạn chỉ có thể .. .CommandText = "SELECT * FROM table WHERE parentid =" & myparam & "; " –

1

dụ Alternative trả lại một lệnh từ một chức năng:

Function BuildCommand(conn As ADODB.Connection) As ADODB.Command 
    Dim cmd As ADODB.Command 
    Set cmd = New ADODB.Command 
    cmd.ActiveConnection = conn 
    cmd.CommandType = adCmdText 
    cmd.Parameters.Append cmd.CreateParameter("@name", adVarChar, adParamInput, 255, "Dave") 
    cmd.CommandText = "SELECT * FROM users WHERE name = @name;" 
    Set BuildCommand = cmd 
End Function 

Một vài điều cần lưu ý:

  1. Khi sử dụng adVarChar kiểu dữ liệu, lập luận kích thước để cmd.CreateParameter (ví dụ 255) là bắt buộc . Không cung cấp nó kết quả một lỗi thời gian chạy 3708: Ứng dụng xác định hoặc đối tượng xác định lỗi, như đã nêu trong documentation:

    Nếu bạn chỉ định một kiểu dữ liệu chiều dài thay đổi trong Type luận, bạn phải vượt qua một đối số Size hoặc đặt thuộc tính Size của đối tượng Parameter trước khi thêm nó vào bộ sưu tập Parameters; nếu không, sẽ xảy ra lỗi.

  2. Nếu tài sản cmd.ActiveConnection được thiết lập khi cmd.CommandText được thiết lập, và cmd.CommandText chứa tên thông số, cmd.Parameters sẽ được áp dụng cho phù hợp. Gọi cmd.Parameters.Append sau đó có thể dẫn đến trùng lặp. Ví dụ:

    cmd.ActiveConnection = conn 
    cmd.CommandType = adCmdText 
    Debug.Print cmd.Parameters.Count ' 0 
    
    cmd.CommandText = "SELECT * FROM users WHERE name = @name;" 
    Debug.Print cmd.Parameters.Count ' 1 
    
    cmd.Parameters.Append cmd.CreateParameter("@name", adVarChar, adParamInput, 255, "Dave") 
    Debug.Print cmd.Parameters.Count ' 2 
    

    Tôi tin rằng đây là những gì có nghĩa là trong documentation, đó là hơi không chính xác:

    Nếu tài sản được chế biến của đối tượng lệnh được thiết lập là True và đối tượng lệnh là ràng buộc với một kết nối mở khi bạn thiết lập thuộc tính CommandText, ADO chuẩn bị truy vấn (nghĩa là, một biểu mẫu đã được biên dịch của truy vấn được nhà cung cấp lưu trữ) khi bạn gọi phương thức Execute hoặc Open.

    Giải pháp thay thế, hoặc đặt cmd.CommandText hoặc cmd.ActiveConnection sau khi thêm thông số.

Các vấn đề liên quan