SQL中的SQL命名变量

时间:2015-03-18 14:52:12

标签: sql sql-server excel-vba vba excel

我有一个在Excel中运行的查询,其中包含可在工作簿中更改的变量参数。

在整个SQL语句中多次引用它,因此我在Select之前声明了一个变量(@Days),然后在整个查询中引用它。

这在管理工作室很好用。

如果我尝试在VBA中执行此操作,则会收到应用程序定义或对象定义错误。

如果我取消注释我的剪贴板代码,并将结果粘贴到管理工作室,它就不会执行任何问题。 如果我在.Refresh之前停止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

我将其分解为测试场景。 Test1失败。查询无法更新。 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 个答案:

答案 0 :(得分:1)

我认为问题在于,当您通过ODBC执行查询时,您无法声明临时变量@Days,就像将剪贴板内容粘贴到SSMS中一样,尽管我可能错了。

正如Sean Lange所说,这不是理想的做法,但您可以在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在服务器上执行的操作相同。