所有MS Access查询到SQL文件

时间:2009-09-14 19:29:03

标签: sql ms-access

我有一个包含10多个查询的MS Access数据库,需要每周更新一次。分别导出每个,然后将每个单独上传到我服务器上的SQL是一件非常痛苦的事。

我尝试将Access数据库直接连接到我的SQL服务器,但由于安全原因,我的服务器不允许这样做。

我找到了一个模块,它会将查询打印在一个文件中,但它只打印标题,这很有用但不完全正是我要找的。

这是模块代码:

Public Sub IterateQueryDefsCollection()

Dim dbMain As DAO.Database

Dim qdf As DAO.QueryDef
Dim qdfTemp As DAO.QueryDef

Set dbMain = CurrentDb

For Each qdf In dbMain.QueryDefs
Debug.Print qdf.Name 'Prints name of query
Set qdfTemp = dbMain.QueryDefs(qdf.Name)
Debug.Print qdfTemp.SQL 'Prints SQL Syntax of query
Next

End Sub

我不编写这些代码,而且我仍然是SQL的新手,所以我的问题就是......有没有办法让我的所有查询及其数据都导出到.sql文件。< / p>

提前谢谢。

3 个答案:

答案 0 :(得分:1)

您的SQL服务器的身份验证过程无法“知道”尝试连接到哪个或哪个应用程序。如果您提供有效凭据,则它应接受连接尝试。正常连接到SQL Server时,您提供什么类型的凭据? (当它工作时)当您指定Access尝试连接的凭据时使用相同的凭据,并且Access连接也将起作用。如果您在访问内部创建了链接表,Access应该要求您指定这些连接凭据。一旦有了连接到sql server的有效链接表,就可以对SQL Server表运行Access查询(使用Access Linked Table作为指针)

答案 1 :(得分:1)

我很困惑为什么你想要每周更新十个查询。在我看来这些应该是参数驱动等。请注意,以下内容不会移动数据。在我看来,代码中的一些追加查询应该很好地处理。

以下是我编写的一个模块,用于尝试将Access MDB中的所有查询升迁到服务器。请注意,由于其中一些查询是“堆叠”的,即它们称为其他查询,因此您必须多次运行此子例程,直到它不再升级为止。

    Sub CopyAllQueriesAsViewsDAO()
        Dim strError As String, strQueryName As String, lngQueryID As Long
        Dim Q As QueryDef, blnSuccessfulQ As Boolean
        Dim strSQL As String, strNewSQL As String, strConnect As String
        Dim intCountFailure As Integer, intCountSuccessful As Integer
        Dim intAlreadyAnError As Integer, strAction As String

        Dim mydatabase As DAO.Database, myquerydef As DAO.QueryDef

    On Error GoTo tagError

        strConnect = "ODBC;DRIVER={sql server};DATABASE=" & _
            strTestDatabaseName & ";SERVER=" & strSQLServerName & ";" & _
            "Trusted_Connection=Yes"
        DoCmd.Hourglass True


        For Each Q In dbsPermanent.QueryDefs
            intAlreadyAnError = 0
            strQueryName = Q.Name
            If Left(strQueryName, 4) = "~sq_" Then
            Else
                strError = ""
                strAction = ""
                lngQueryID = FetchQueryID(strQueryName, blnSuccessfulQ) ' Add the record or locate the ID
                If blnSuccessfulQ = False Then
                    strNewSQL = adhReplace(Q.SQL, vbCrLf, " ")
                    strNewSQL = Left(strNewSQL, InStr(strNewSQL, ";") - 1)
                    strNewSQL = ConvertTrueFalseTo10(strNewSQL)

    tagRetryAfterCleanup:
                    Set myquerydef = dbsPermanent.CreateQueryDef("") 'Q.Name & " DAO Test")
                    myquerydef.ReturnsRecords = False
                    myquerydef.Connect = strConnect
                    myquerydef.SQL = "CREATE VIEW [" & strQueryName & "] AS " & strNewSQL
                    myquerydef.Execute
                    myquerydef.Close

                    strSQL = "UPDATE zCreateQueryErrors SET zcqeErrorMsg = 'Successful' " & _
                        "WHERE ID=" & lngQueryID & ";"
                    CurrentDb.Execute strSQL, dbFailOnError
                    intCountSuccessful = intCountSuccessful + 1
                End If
            End If
    tagResumeAfterError:
        Next

        DoCmd.Hourglass False

        MsgBox "There were " & intCountSuccessful & " successful." & vbCrLf & _
            intCountFailure & " failures."


        Exit Sub

    tagError:
      '  MsgBox Err.Description

      Dim errX As DAO.Error, strFunctionName As String, intPosnFunction As Integer
      Dim strThisError As String

        If Errors.Count > 1 Then
            For Each errX In DAO.Errors
                strThisError = mID(errX.Description, 48)
                If intAlreadyAnError > 5 Then  ' Hit 10 errors so don't attempt to clean up the query
                    If errX.Number <> 3146 Then
                        strError = strError & "After fix: " & errX.Number & ": " & strThisError & " "
                    End If
                Else
                    Select Case errX.Number
                    Case 3146 ' Ignore as this is the generic OLE db error
                    Case 195 '  'xxx' is not a recognized function name. > Insert dbo. in front of function name
                        intAlreadyAnError = intAlreadyAnError + 1
                        strFunctionName = mID(strThisError, 2, InStr(2, strThisError, "'") - 2)
                        intPosnFunction = InStr(strNewSQL, strFunctionName)
                        strNewSQL = Left(strNewSQL, intPosnFunction - 1) & "dbo." & mID(strNewSQL, intPosnFunction)
                        strAction = strAction & "Inserted dbo for " & strFunctionName & " "
                        Resume tagRetryAfterCleanup
                    ' The ORDER BY clause is invalid in views, .... , unless TOP is also specified.
                    Case 1033 'TOP 100 PERCENT
                        strNewSQL = Left(strNewSQL, 7) & " TOP 100 PERCENT " & mID(strNewSQL, 8)
                        strAction = strAction & "Inserted TOP 100 PERCENT "
                        Resume tagRetryAfterCleanup
                    Case Else
                        strError = strError & errX.Number & ": " & mID(errX.Description, 48) & " "
                    End Select
                End If
            Next errX
        Else
            strError = Err.Number & ", " & Err.Description
        End If

        strSQL = "UPDATE zCreateQueryErrors SET zcqeErrorMsg = '" & adhHandleQuotes(strError) & "', " & _
            "zcqeAction = '" & strAction & "', zcqeFinalSQL = '" & adhHandleQuotes(strNewSQL) & "' " & _
            "WHERE ID=" & lngQueryID & ";"
        CurrentDb.Execute strSQL, dbFailOnError
        intCountFailure = intCountFailure + 1
        Resume tagResumeAfterError

    End Sub

Public Function ConvertTrueFalseTo10(strIncoming As String)

    Dim strIntermediate As String, intPosn As Integer

    strIntermediate = strIncoming

    intPosn = InStr(strIntermediate, "=false")
    While intPosn <> 0
        strIntermediate = Left(strIntermediate, intPosn - 1) & "=0" & mID(strIntermediate, intPosn + 6)
        intPosn = InStr(strIntermediate, "=false")
    Wend

    intPosn = InStr(strIntermediate, "=true")
    While intPosn <> 0
        strIntermediate = Left(strIntermediate, intPosn - 1) & "=1" & mID(strIntermediate, intPosn + 5)
        intPosn = InStr(strIntermediate, "=true")
    Wend


    ConvertTrueFalseTo10 = strIntermediate

End Function


Function FetchQueryID(strQueryName As String, blnSuccessfulQ As Boolean) As Long

    Dim myRS As Recordset
    Dim strSQL As String
    blnSuccessfulQ = False

    strSQL = "SELECT ID, zcqeErrorMsg FROM zCreateQueryErrors " & _
        "WHERE zcqeName='" & strQueryName & "';"
    Set myRS = dbsPermanent.OpenRecordset(strSQL, dbOpenSnapshot)
    If myRS.EOF Then
        Set myRS = dbsPermanent.OpenRecordset("zCreateQueryErrors", dbOpenSnapshot)
        myRS.AddNew
        myRS!zcqeName = strQueryName
        myRS.Update
        myRS.Move 0, myRS.LastModified
        FetchQueryID = myRS!ID
    Else
        myRS.MoveFirst
        FetchQueryID = myRS!ID
        If myRS!zcqeErrorMsg = "Successful" Then
            blnSuccessfulQ = True
        End If
    End If
    myRS.Close
    Set myRS = Nothing

End Function

Public Function adhHandleQuotes(strValue As String) As String
    ' Fix up all instances of a quote within a string by
    ' breaking up the string, and inserting Chr$(34) whereever
    ' you find a quote within the string.  This way, Jet can
    ' handle the string for searching.
    '
    ' From Access 97 Developer's Handbook
    ' by Litwin, Getz, and Gilbert (Sybex)
    ' Copyright 1997.  All rights reserved.
    '
    ' Solution suggested by Jurgen Welz, a diligent reader.

    ' In:
    '   strValue:   Value to fix up.
    ' Out:
    '   Return value: the text, with quotes fixed up.
    ' Requires:
    '   adhReplace (or some other function that will replace
    '       one string with another)
    '
    ' Example:
    '    adhHandleQuotes("John "Big-Boy" O'Neil") returns
    '     "John " & Chr$(34) & "Big-Boy" & Chr$(34) & " O'Neil"

   Const QUOTE As String = """"
   Const SingleQUOTE As String = "'"

   adhHandleQuotes = adhReplace(strValue, SingleQUOTE, _
    SingleQUOTE & SingleQUOTE)
 End Function

 Function adhReplace(ByVal varValue As Variant, _
  ByVal strFind As String, ByVal strReplace As String) As Variant

     ' Replace all instances of strFind with strReplace in varValue.

     ' From Access 97 Developer's Handbook
     ' by Litwin, Getz, and Gilbert (Sybex)
     ' Copyright 1997.  All rights reserved.

     ' In:
     '    varValue: value you want to modify
     '    strFind: string to find
     '    strReplace: string to replace strFind with
     '
     ' Out:
     '    Return value: varValue, with all occurrences of strFind
     '     replaced with strReplace.

     Dim intLenFind As Integer
     Dim intLenReplace As Integer
     Dim intPos As Integer

     If IsNull(varValue) Then
         adhReplace = Null
     Else
         intLenFind = Len(strFind)
         intLenReplace = Len(strReplace)

         intPos = 1
         Do
             intPos = InStr(intPos, varValue, strFind)
             If intPos > 0 Then
                 varValue = Left(varValue, intPos - 1) & _
                  strReplace & mID(varValue, intPos + intLenFind)
                 intPos = intPos + intLenReplace
             End If
         Loop Until intPos = 0
     End If
     adhReplace = varValue
 End Function

答案 2 :(得分:0)

你问是否有办法为此导出SQL文件。有,但你必须编写代码来执行它,即遍历查询结果的每一行并编写一个insert语句(即INSERT INTO(Field1,Field2)VALUES(value1,value2)(value3,value4)等等,它是目标数据库引擎的正确SQL方言。

但是,它可能很容易导出到CSV文件(或制表符分隔或其他),并让您的数据库导入该文件。

但是,没有真正的方法可以知道如何回答你的问题,因为关于查询实际执行的内容还不够详细。如果它们是INSERT语句,则上述内容将完全符合您的要求。

如果它们是更新,那就更复杂了。

但也许以上内容可以让你开始。