Excel VBA代码中带有变量声明的T-SQL查询失败

Excel VBA代码中带有变量声明的T-SQL查询失败,sql,tsql,vba,excel,Sql,Tsql,Vba,Excel,在VBA中使用“declare”和“set”函数运行SQL查询时遇到问题 Sheets("Arkusz1").Select connstring = _ "ODBC;DRIVER=SQL Server;SERVER=my_database_server;UID=user;PWD=password;APP=Microsoft Office 2010;WSID=some_id;DATABASE=mydatabase" With ActiveSheet.QueryTables.Add(Connect

在VBA中使用“declare”和“set”函数运行SQL查询时遇到问题

Sheets("Arkusz1").Select
connstring = _
"ODBC;DRIVER=SQL Server;SERVER=my_database_server;UID=user;PWD=password;APP=Microsoft Office 2010;WSID=some_id;DATABASE=mydatabase"

With ActiveSheet.QueryTables.Add(Connection:=connstring, Destination:=Worksheets("Arkusz1").Range("A1"), Sql:=Array( _
"declare @dzisiaj date" & Chr(13), _
"set @dzisiaj = getdate()" & Chr(13), _
"select @dzisiaj as dzisiaj"))

    .BackgroundQuery = False
    .Refresh
End With
在SQL Server 2012中,该代码工作正常,但。。。当我将它嵌入其中时,它会给我一个运行时错误“1004”。VBA代码也适用于其他查询

我的完整SQL查询大约有90行,其中包含2个变量声明(一个声明是另一个30行SQL查询的值),因此必须包含变量声明:)


如何解决这个问题

我对vb和vba还是个新手,我自己也在学习,但我知道你可以在vb.net中声明和写入变量,然后将变量输入到嵌入式SQL脚本中。我认为你可以在vba中做同样的事情。以下是我的建议

  • 声明一个vb字符串,如SQL\u Var\u 1
  • 将30行SQL查询作为单独的查询插入主查询之前
  • 将30行查询的结果写入vb字符串SQL\u Var\u 1
  • 从主SQL查询中删除声明,但保留对这些变量的引用
  • 在嵌入式主查询中引用SQL_Var_1作为输入参数,使用与主查询中使用的名称完全相同的名称(即@Dzisaj),如

  • 如果您对这两个SQL变量都遵循这些步骤,您应该能够获得与使用声明的SQL变量相同的结果。

    我对vb和vba仍然是新手,并在学习自己,但我知道您可以在vb.net中声明和写入变量,然后将变量输入嵌入式SQL脚本。我认为你可以在vba中做同样的事情。以下是我的建议

  • 声明一个vb字符串,如SQL\u Var\u 1
  • 将30行SQL查询作为单独的查询插入主查询之前
  • 将30行查询的结果写入vb字符串SQL\u Var\u 1
  • 从主SQL查询中删除声明,但保留对这些变量的引用
  • 在嵌入式主查询中引用SQL_Var_1作为输入参数,使用与主查询中使用的名称完全相同的名称(即@Dzisaj),如

  • 如果对这两个SQL变量都执行这些步骤,则应该能够获得与使用声明的SQL变量相同的结果。

    我已经找到了答案。关键是使用ADODB连接通过SQL查询导入数据。还需要在Visual Basic编辑器中的工具->参考中检查Microsoft Active X Data Objects 2.0库(快捷方式:Excel中的Alt+F11)

    下面是我的VBA代码示例:

        Sub sql_query_import()
    
        ' Declarations
        Dim Cn As ADODB.Connection
        Dim Server_Name As String
        Dim Database_Name As String
        Dim User_ID As String
        Dim Password As String
        Dim SQLStr As String
        Dim rs As ADODB.Recordset
        Set rs = New ADODB.Recordset
    
        ' Server connection settings
        Server_Name = "192.168.1.106\my_database" ' IP of server name
        Database_Name = "mydatabase" ' Database name
        User_ID = "myusername" ' User name
        Password = "mypassword" ' User password
    
        ' SQL Query
        SQLStr = "SET NOCOUNT ON " & Chr(13) ' it's mandatory if you don't want to get error 3704
        SQLStr = SQLStr & "declare @dzisiaj date " & Chr(13)
        SQLStr = SQLStr & "set @dzisiaj = getdate() " & Chr(13)
    SQLStr = SQLStr & "select @dzisiaj as 'today'
    
        ' Connect to database
        Set Cn = New ADODB.Connection
        Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
        ";Uid=" & User_ID & ";Pwd=" & Password & ";"
    
        ' Start connection
        rs.Open SQLStr, Cn, adOpenStatic
    
        ' Load data
        With rs
            For i = 1 To .Fields.Count
                Worksheets(1).Cells(1, i) = .Fields(i - 1).Name ' Include column name if not - delete it
            Next i
        End With
        Worksheets(1).Cells(2, 1).CopyFromRecordset rs ' Start loading data to Cell A2
    
    
        rs.Close
        Set rs = Nothing
        Cn.Close
        Set Cn = Nothing
        End Sub
    
    如果您不想得到错误3704,那么在SQL查询中使用“SET NOCOUNT ON”是必要的。 此外,使用

    SQLStr = "SET NOCOUNT ON " & Chr(13) ' it's mandatory if you don't want to get error 3704
    SQLStr = SQLStr & "declare @dzisiaj date " & Chr(13)
    

    包含多行SQL查询是一种更有效的方法:)

    我想出来了。关键是使用ADODB连接通过SQL查询导入数据。还需要在Visual Basic编辑器中的工具->参考中检查Microsoft Active X Data Objects 2.0库(快捷方式:Excel中的Alt+F11)

    下面是我的VBA代码示例:

        Sub sql_query_import()
    
        ' Declarations
        Dim Cn As ADODB.Connection
        Dim Server_Name As String
        Dim Database_Name As String
        Dim User_ID As String
        Dim Password As String
        Dim SQLStr As String
        Dim rs As ADODB.Recordset
        Set rs = New ADODB.Recordset
    
        ' Server connection settings
        Server_Name = "192.168.1.106\my_database" ' IP of server name
        Database_Name = "mydatabase" ' Database name
        User_ID = "myusername" ' User name
        Password = "mypassword" ' User password
    
        ' SQL Query
        SQLStr = "SET NOCOUNT ON " & Chr(13) ' it's mandatory if you don't want to get error 3704
        SQLStr = SQLStr & "declare @dzisiaj date " & Chr(13)
        SQLStr = SQLStr & "set @dzisiaj = getdate() " & Chr(13)
    SQLStr = SQLStr & "select @dzisiaj as 'today'
    
        ' Connect to database
        Set Cn = New ADODB.Connection
        Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & _
        ";Uid=" & User_ID & ";Pwd=" & Password & ";"
    
        ' Start connection
        rs.Open SQLStr, Cn, adOpenStatic
    
        ' Load data
        With rs
            For i = 1 To .Fields.Count
                Worksheets(1).Cells(1, i) = .Fields(i - 1).Name ' Include column name if not - delete it
            Next i
        End With
        Worksheets(1).Cells(2, 1).CopyFromRecordset rs ' Start loading data to Cell A2
    
    
        rs.Close
        Set rs = Nothing
        Cn.Close
        Set Cn = Nothing
        End Sub
    
    如果您不想得到错误3704,那么在SQL查询中使用“SET NOCOUNT ON”是必要的。 此外,使用

    SQLStr = "SET NOCOUNT ON " & Chr(13) ' it's mandatory if you don't want to get error 3704
    SQLStr = SQLStr & "declare @dzisiaj date " & Chr(13)
    
    是包含多行SQL查询的更有效的方法:)