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

Un-nesting nested MS Access sql queries

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

我最大的问题是,他将查询嵌套了 5 层以上的深度,而我很难以这种方式阅读。他编写的查询通常采用这种格式,但要复杂得多。

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

和 CustomQuery{1,2,3} 在它们引用多个其他子查询时都以完全相同的方式编写。我不仅发现这非常难以阅读,而且我担心如果我修改其中一个查询,它可能在我不知道的另一个查询的其他地方调用,这将破坏另一个报告。我想知道是否有一种方法可以分析所有查询,以确定哪些查询被其他查询调用 and/or 是否有某种工具可以自动取消嵌套它们,或者我是否只需要跟踪他们都是手动的。

Access 中内置的 Object Dependencies 窗格对您很有帮助。请注意,您需要在检查时打开名称自动更正,即使您在其余时间关闭它,这通常是最好的。此外,它不会显示 VBA 对查询的代码引用,因此您必须通过搜索自行检查。

是的,有一种方法可以确定一个查询是否被另一个查询使用。我创建了一个表单来执行此操作,以便我可以 select 多个数据库对象并同时删除它们,因为我讨厌 Access 只允许您本机删除 1 个数据库对象(即表单、table 等。 .) 一次,我想确保我想删除的数据库对象没有在别处被引用。

不幸的是,我无法从我的工作计算机将表格上传到任何地方,他们阻止了那些东西。但是,我可以告诉您,您要做的是搜索数据库中每个 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

这是一张正在运行的表格图片,可以让您了解一下: