2017-04-03 30 views
0

我敬酒,想不通爲什麼我在 rst.Open STRSQLADODB Recordset.Open給語法錯誤擅長於SQL

我已經試過了線得到一個語法錯誤rst.Open strSQL,cnt,adOpenStatic,adLockReadOnly,adCmdText

但它仍然給我一個錯誤。

我有一個偷偷的猜疑,它與strSQL如何獲取單元格值並將其追加到字符串的末尾。

任何幫助,高度讚賞。

Public Sub EzPz() 

Dim cnt As ADODB.Connection 
Dim rst As ADODB.Recordset 


Set cnt = New ADODB.Connection 
Set rst = New ADODB.Recordset 


Dim strSQL As String 

'Open connection 
cnt.ConnectionString = "Driver={SQL Server};Server=HIDDEN;Database=HIDDENXX;Trusted_Connection=yes;UID=HIDDENU;PWD=HIDDENP;" 
cnt.Open 

'String for SQL cmd 
Dim p1 As Range 
Set p1 = ActiveSheet.Cells(1, 4) 
strSQL = "SELECT DBNAME.vItem.Upc FROM DBNAME.vItem WHERE vItem.ItemDesc=" & p1.Value 



rst.ActiveConnection = cnt  
rst.Open strSQL 

ActiveSheet.Cells(1, 1).CopyFromRecordset rst 

End Sub 
+0

兩個大問題和你的問題 - 兩件大事1)你正在顯示你的用戶名和密碼。你現在需要改變它們。 2)你正在使用字符串連接 - 這是一個安全問題,任何公共網站都會在幾個小時內被黑客入侵。最後是錯誤的原因是你沒有在引號中包圍字符串值 – Hogan

+0

我改變了密碼和用戶名哈哈HIDDENU和HIDDENP不是用戶及密碼:P 這是否意味着rst。打開「strSQL」 – Mjall2

+0

我是很高興聽到那些不是你的用戶名和密碼:)沒有 - 我的意思是字符串常量在sql需要引號中的實際值 - 但許多答案涵蓋了這一點。 – Hogan

回答

3

您的代碼需要SQL注入。您可以將字符串文字用單引號as shown in this answer括起來以解決語法錯誤,但這不能解決嚴重的安全問題。

Obligatory XKCD

那麼,你如何安全參數查詢?用參數化查詢

Dim conn As ADODB.Connection 
Set conn = New ADOBD.Connection 
.ConnectionString = "connection string ideally using Windows Authentication" 
.Open 

理想情況下,您的連接字符串不包含任何用戶名或密碼;您的服務器需要配置爲支持Windows身份驗證才能正常工作 - 然後,查詢將使用登錄的Windows用戶的憑據執行,並且該用戶的權限的權限爲

Dim cmd As ADODB.Command 
Set cmd.ActiveConnection = conn 
cmd.CommandType = adCmdText 
cmd.CommandText = "SELECT DBNAME.vItem.Upc FROM DBNAME.vItem WHERE vItem.ItemDesc = ?;" 

設置一個Command對象。 CommandText將作爲您的SQL語句,但不是將參數連接到它中,而是使用每個問號的?問號。

Dim itemDesc As ADODB.Parameter 
Set itemDesc = New ADODB.Parameter 
itemDesc.Type = adVarChar 
itemDesc.Direction = adParamInput 
itemDesc.Value = p1.Value 

cmd.Parameters.Append(itemDesc) 

在SQL語句中的每個?問號創建Parameter。您必須爲每個?問號提供參數。

Dim results As ADODB.Recordset 
Set results = cmd.Execute 

通過調用命令的Execute方法獲得Recordset;服務器處理參數。

ActiveSheet.Cells(1, 1).CopyFromRecordset results 

如果一切順利,Recordset包含您的結果。

總是使用參數化查詢:連接到SQL語句的用戶輸入是瘟疫。

+0

嘿馬特,謝謝你的詳細解答。我建立這個代碼的方法是從準系統開始,然後從那裏開始。我不會將UID和PWD留在連接字符串中,因爲它是一家公司,所以爲我的帳戶設置Windows身份驗證需要時間。 我會從你關於使用CommandText的回答中學習,並在構建代碼時應用它們。 – Mjall2

+1

只是說,*正確的*方法是從頭開始*安全地構建您的代碼*。你目前的做法是'Dave O'Brian'不能登錄到許多網站,因爲他的用戶名包含單引號。使用用戶輸入**的數據庫訪問代碼必須**正確參數化 - 沒有ifs,沒有buts,沒有藉口。 –

+0

公平。對你的問題 - 我想遍歷一整列的ItemDesc並在查詢中運行它,每次運行查詢時循環查詢和輸出的運行以及更改參數是明智的選擇。 – Mjall2

2

SQL需要理解字符串文字,您需要用單引號分隔字符串文本以使語法有效。

你可以試試看看是否有效?

strSQL = "SELECT DBNAME.vItem.Upc FROM DBNAME.vItem WHERE vItem.ItemDesc= '" & p1.Value & "'" 
+0

解決了它。 現在我有一個錯誤來訪問SELECT語句,但我會告訴我的管理員:D! – Mjall2

+0

@ Mjall2保留複選標記,如果你想要的話,但我敦促你至少*閱讀*我的答案。 –

+0

@ Mjall2我同意Mat's Mug在這裏。你應該通過他提供的深入答案。 – sktneer