取消嵌套嵌套的MS Access SQL查询

时间:2015-01-05 19:09:41

标签: ms-access ms-access-2010 legacy legacy-code legacy-database

我已经获得了一个小型Access数据库。创建它的人编写了许多自定义查询来生成报告。我的任务是修改报告,最初编写查询的人已经离开,没有留下任何文档。

我最大的问题是他将查询嵌套在5级以上,这对我来说是难以理解的。他写的查询通常都有这种格式,但更复杂。

SELECT thisCol, thatCol, theOtherCol
FROM CustomQuery1, CustomQuery2, CustomQuery3 

CustomQuery {1,2,3}每个都以与引用多个其他子查询完全相同的方式编写。我不仅难以阅读这个难以置信的内容,而且我担心如果我修改其中一个查询,或许它在其他查询中调用,我不知道这会打破另一个报告。我想知道是否有分析所有查询的方法,以确定哪些查询被其他查询调用和/或是否有某些工具可以自动取消嵌套或者如果我只需要手动追踪它们。

2 个答案:

答案 0 :(得分:3)

有助于您获得成功的一件事是Object Dependencies窗格,它内置于Access中。请注意,您需要在检查时启用“名称自动更正”,即使您在其余时间关闭它,通常也是最好的。此外,它不会显示对查询的VBA代码引用,因此您必须通过搜索自己检查它们。

答案 1 :(得分:0)

是的,有一种方法可以确定另一个查询是否使用了查询。我创建了一个表单来完成这个,这样我就可以选择多个数据库对象并同时删除它们因为我讨厌Access如何让你一次只能原生地删除1个数据库对象(即表单,表格等等),而我我想确保我想要删除的数据库对象没有在其他地方引用。

不幸的是,我无法从我的工作计算机上传任何表格,他们会阻止这些内容。但是,我可以告诉您,您需要做的是搜索数据库中每个QueryDef的QueryDef.SQL。

你必须稍微分开一点,但这是我写的VBA。

Private Sub ListObjects_Click()
' Search all queries for SQL containing the specified string.
Screen.MousePointer = 11
On Error GoTo Err_SearchQueries

Dim db As DAO.Database
Dim qdf As QueryDef

Dim varTest As Variant
Dim lngSearchCount As Long
Dim lngFoundCount As Long
Set db = CurrentDb

lngFoundCount = 0
lngSearchCount = 0

Me.txtTblSearch = "*** Beginning search for " & Me.ListObjects.Column(0) & "..." & vbCrLf

'Get a count of the database objects that will be searched
For Each qdf In db.QueryDefs
    With qdf
        If Left(qdf.Name, 3) = "~sq" Then
          lngSearchCount = lngSearchCount + 1
        End If
    End With
Next qdf

For Each qd In db.QueryDefs
    If InStr(1, qd.SQL, Me.ListObjects.Column(0)) > 0 Then
      If Left(qd.Name, 4) = "~sq_" Then
        If Mid(qd.Name, 5, 1) = "f" Then
          Me.txtTblSearch = txtTblSearch & "found in Form " & Right(qd.Name, Len(qd.Name) - 5) & vbCrLf
          lngFoundCount = lngFoundCount + 1
        ElseIf Mid(qd.Name, 5, 1) = "r" Then
          Me.txtTblSearch = txtTblSearch & "found in Report " & Right(qd.Name, Len(qd.Name) - 5) & vbCrLf
          lngFoundCount = lngFoundCount + 1
        ElseIf Mid(qd.Name, 5, 1) = "d" Then
          Me.txtTblSearch = txtTblSearch & "found in Report " & Right(qd.Name, Len(qd.Name) - 5) & vbCrLf
          lngFoundCount = lngFoundCount + 1
        ElseIf Mid(qd.Name, 5, 1) = "c" Then
          Me.txtTblSearch = txtTblSearch & "found in a control in Form " & Right(qd.Name, Len(qd.Name) - 5) & vbCrLf
          lngFoundCount = lngFoundCount + 1
        End If
      Else
        Me.txtTblSearch = txtTblSearch & "found in Query " & qd.Name & vbCrLf
        lngFoundCount = lngFoundCount + 1
      End If
    End If
Next qd
Set qd = Nothing
Set db = Nothing



Exit_SearchQueries:
Set qdf = Nothing
Set db = Nothing
Me.txtTblSearch = Me.txtTblSearch & vbCrLf
Me.txtTblSearch = Me.txtTblSearch & "*** Searched " & lngSearchCount & _
" objects, found " & lngFoundCount & " occurrences."
Screen.MousePointer = 0
Exit Sub

'If an error is thrown, alert the user as to which object caused it
Err_SearchQueries:
MsgBox Err.Description, vbExclamation, "Error " & Err.Number
If IsNull(qd.Name) Then
Else
  MsgBox "Possible issue with query: " & qd.Name
End If
Screen.MousePointer = 0
Resume Exit_SearchQueries


End Sub

这是一张实际形式的图片,为您提供一个想法:

enter image description here