2015-03-18 3 views
0

У меня есть запрос, который выполняется в Excel с переменным параметром, который можно изменить в книге.SQL Именованные переменные в VBA

Это ссылается несколько раз на весь SQL-запрос, и поэтому я объявлял переменную (@Days) перед выбором, а затем ссылался на нее в течение всего запроса.

Это прекрасно работает в студии управления.

Если я попытаюсь выполнить это в VBA, я получаю определенную или определяемую объектами ошибку.

Если я раскомментирую свой код буфера обмена и вставлю результат в студию управления, это не вызовет проблем. Если я остановил VBA до. Обновить и вручную обновить запрос, он обновится.

VBA ниже:

Sub Refresh() 


Dim Days As String 
Dim SQLStat As String 
Dim RChar As Integer 

Days = Sheets("Data").Range("A1").Value 

' Gets current Query, and strips off declaration 
SQLStat = ActiveWorkbook.Connections("Query").ODBCConnection.CommandText 
SQLStat = Right(SQLStat, (Len(SQLStat) - (InStr(1, SQLStat, "Select") - 1))) 

' Adds Declaration with new days value. 
SQLStat = "Declare @Days integer set @Days = " & Days & " " & Chr(13) & SQLStat 


' Puts SQL in clipboard for test purposes 
'Dim clipboard As MSForms.DataObject 
'Set clipboard = New MSForms.DataObject 
'clipboard.SetText SQLStat 
'clipboard.PutInClipboard 


With ActiveWorkbook.Connections("Query").ODBCConnection 
    .BackgroundQuery = False 
    .CommandText = SQLStat 
    .Refresh 
End With 

MsgBox "Refreshed" 

End Sub 

Я разделить на это в тестовый сценарий. Тест1 не работает. Запрос не обновляется. Test2 Обновляет, как вы ожидали.

Sub Test1() 
Dim SqlStr As String 
Dim Days As String 

Days = Sheets("test").Range("A1").Value 
SqlStr = "declare @Days int set @Days = " & Days & " select dateadd(day,@days,getdate())" 

With ActiveWorkbook.Connections("Query").ODBCConnection 
    .CommandText = SqlStr 
    .Refresh 
End With 

End Sub 


Sub Test2() 
Dim SqlStr As String 
Dim Days As String 

Days = Sheets("test").Range("A1").Value 
SqlStr = "select dateadd(day," & Days & ",getdate())" 

With ActiveWorkbook.Connections("Query").ODBCConnection 
    .CommandText = SqlStr 
    .Refresh 
End With 

End Sub 
+1

У вас есть Дни, определенные как строка в VBA и int в вашем sql. Я не думаю, что вы можете сделать этот тип динамического sql через VBA. Почему бы не создать хранимую процедуру с параметром @Days? Затем вы можете просто выполнить свою процедуру. –

+0

Не имеет значения. Я только что изменил параметр Days VBA на RepDays, и он делает то же самое. – OWSam

+0

Правильно, потому что вы должны делать это в хранимой процедуре. Речь идет не о имени, а о том, как вы это делаете. –

ответ

1

Я думаю, что проблема в том, что при выполнении запроса через ODBC, вы не можете объявить временную переменную @Days, как вы можете, когда вы вставить содержимое буфера обмена в SSMS, хотя я могу быть неправ.

Как отметил Шон Ланге, это не идеальный способ сделать это, но вы можете построить свой весь запрос в VBA, а затем передать это серверу. Что-то вроде этого:

Dim Days As String 
Dim SQLStat As String 
Dim RChar As Integer 

Days = Sheets("Data").Range("A1").Value 

' Gets current Query, and strips off declaration 
SQLStat = ActiveWorkbook.Connections("Query").ODBCConnection.CommandText 
SQLStat = Right(SQLStat, (Len(SQLStat) - (InStr(1, SQLStat, "Select") - 1))) 

'Build the new query string using the actual value of Days 
SQLStat = Replace(SQLStat, "@Days", Days) 

Это будет строить всю строку запроса в VBA, таким образом, обходя необходимость иметь @Days локальную переменную, объявленную на сервере. Replace() делает в VBA то, что делает @Days на сервере.

Смежные вопросы