簡體   English   中英

如何在SQL插入語句中直接使用變量

[英]How to use variables in SQL insert statement directly

我有一個 SQL 語句:

Dim Xdb As DAO.Database
Set Xdb = CurrentDb
Dim v1 As Integer
Dim v2 As String
With Me
    v1 = 1
    v2 = Trim(.txt2)
End With
Dim Sql As String
Sql = "Insert Into TblCustomers" _
& " (ID,FName)" _
& " Values " _
& " (1,'"& v2 &"')"

我想在 SQL 語句中的值中使用這個變量“V2”,但不使用引號。

喜歡:

Sql = "Insert Into TblCustomers" _
& " (ID,FName)" _
& " Values " _
& " (1,v2)"

如何將“V2”變量正確設置為這樣?

你需要使用這樣的東西:

Dim cmdSQLInsert As ADODB.Command
Set cmdSQLInsert = New ADODB.Command

'Create the query
cmdSQLInsert.CommandText = "Insert Into TblCustomers(ID, FName) Values(?,?)"
cmdSQLInsert.CommandType = adCmdText
cmdSQLInsert.Prepared = True

'Create the parameters
'in this case we will create three parameters
'-----Param 1 (for Field ID)-------------
Dim gParam As ADODB.Parameter
Set gParam = New ADODB.Parameter
With gParam
    .Name = "ID"
    .Direction = adParamInput
    .Type = adInt
    .Value = 1
End With
cmdSQLInsert.Parameters.Append gParam

'-----Param 2 (for FName)-------------
Set gParam = Nothing
Set gParam = New ADODB.Parameter
With gParam
    .Name = "FName"
    .Direction = adParamInput
    .Type = adVarChar
    .Size = 50
    .Value = "FirstNameValue"
End With
cmdSQLInsert.Parameters.Append gParam

'Set the connection property of the command object
Set cmdSQLInsert.ActiveConnection = mySQLConnection

'Execute the command
cmdSQLInsert.Execute

這個問題確實是其他問題的重復(例如此處此處),因為許多 Access 新手都希望並希望能夠直接從 SQL 語句中引用 VBA 變量。 無論是 INSERT、UPDATE、SELECT 等,本質上都是相同的問題。

幾乎所有好的答案最終都會導致參數化的 QueryDefs 或 ADO 命令,我同意這是出於各種原因的最佳實踐方法。 但是很少有評論和答案直接解決這個問題,所以這里有一個不同的答案......

Access SQL 不能直接引用 VBA 模塊變量。 但是,有幾種替代方法可以工作,但它們都有自己的缺點。

  • Access SQL可以直接引用 VBA 模塊中聲明的公共函數。 因為 VBA 函數本質上可以訪問任何其他變量或對象並返回一個值,所以它當然可以返回一個變量的值,否則 SQL 不能直接訪問該值。
    • 這里要意識到的最關鍵的問題是在執行查詢之前必須確保調用此類函數的上下文。 如果引用此類函數的查詢被稱為“亂序”(當變量未正確初始化時),那么它當然會導致預期行為和/或無效數據。

'* From within a VBA module *
Private moduleVariable As String

Public Sub MySub()
  moduleVariable
End Sub

Public Function GetModuleVariable() As String
  GetModuleVariable = moduleVariable
End Function

'--- Example SQL statement ---
'INSERT INTO TblCustomers (ID,FName) VALUES (1, GetModuleVariable())
  • 可以訪問的特殊對象稱為TempVars此處文檔)。 它確實是為與宏一起使用而設計的,但 Access 將其公開為可從 SQL 語句中直接訪問的對象,因此在技術上是允許的。
    • 最大的缺點是值存儲為 VBA 變體,並且 SQL 並不總是正確解釋它們。 使用顯式轉換函數可以解決這個問題。 該示例通過在CDbl()包裝TempVars引用來演示這一點。

'* From within a VBA module *
Public Sub MySub()
  TempVars.Add "myVariable", 123.45
End Sub

'--- Example SQL statement ---
'INSERT INTO products (ID, Amount) VALUES (100, CDbl(TempVars!myVariable))

我剛開始使用 Access,發現接受的答案非常有幫助。 謝謝你,@Pablo Santa Cruz。

我一直在尋找有助於消除代碼中 SQL 注入的解釋。 當我實現這段代碼時,我遇到了參數中未設置值的問題。 我更改了我的引用以使用索引、Parameters(0) 等,然后數據類型不匹配,因為我已將所有參數聲明為字符串。

追查過程發現,在將INSERT語句賦值給cmd.CommandText的時候,自動添加了參數,與數據庫中的元數據相匹配。 因此,必須更改參數 2 和 3 以分別匹配聲明類型的整數和日期時間參數。

有點酷,也許有點令人毛骨悚然。 這是我的例子:

' Create table MyTable( sCol Varchar(255), nCol Integer, dCol DateTime )

Dim conn As New ADODB.Connection
conn.ConnectionString = "Provider=SQLOLEDB.1;Trusted_Connection=yes;Server=Thresher;Database=MyDB;"
conn.Open

Dim cmd As New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandText = "INSERT INTO MyTable( sCol, nCol, dCol ) VALUES (?, ?, ?)"

cmd.Parameters(0).Value = "One"
cmd.Parameters(1).Value = 1
cmd.Parameters(2).Value = #1/1/2001#
cmd.Execute

conn.Close

暫無
暫無

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

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