我有一个 job 桌子

Id
ParentID
jobName
jobStatus

根 ParentID 为 0。

是否可以在 Access 中创建查询来查找给定的根 job?数据库是MDB,没有链接表。Access版本是2003。A job 可以深几层孙子。

有帮助吗?

解决方案

不,不是。SServer 2005 之后的 SQL Server 支持递归查询,但 Access 不支持。

如果您事先知道级别数,则可以编写一个查询,但它不会是递归查询。

在 SQL Server 中,CTE(SQL 扩展)用于:看 http://blog.crowe.co.nz/archive/2007/09/06/Microsoft-SQL-Server-2005---CTE-Example-of-a-simple.aspx

然而,常规 SQL 不支持递归。

其他提示

可以在Access中创建一个查询,找到你定作业的根源。 不要忘记的VBA函数的功率。您可以在VBA模块中创建一个递归函数,并在查询中使用其结果作为输出领域。

示例:

Public Function JobRoot(Id As Long, ParentId As Long) As Long
   If ParentId = 0 Then
      JobRoot = Id
      Exit Function
   End If

   Dim Rst As New ADODB.Recordset
   Dim sql As String
   sql = "SELECT Id, ParentID FROM JobTable WHERE Id = " & ParentId & ";"
   Rst.Open sql, CurrentProject.Connection, adOpenKeyset, adLockReadOnly

   If Rst.Fields("ParentID") = 0 Then
      JobRoot = Rst.Fields("Id")
   Else
      JobRoot = JobRoot(Id, Rst.Fields("ParentID"))    ' Recursive.
   End If

   Rst.Close
   Set Rst = Nothing
End Function

您可以通过使用查询生成器或函数名在查询字段变量只是打字调用从查询这个递归函数。

有将产生的根源。

(我认识的OP是现在一岁,但我不得不回答的时候大家说什么是不可能的可能)。

可以不递归查询。

您可以做的左侧加入一些任意数字,但你只能为你加入去尽可能多的水平。

或者你也可以使用 Celko的 “嵌套集模型” 检索所有的父母。这将需要修改你的表结构,方式,使插入和更新更复杂。

这不能用纯SQL Access中完成的,但有点VBA走一段很长的路要走。

添加一个引用到的 Microsoft脚本运行时工具 - > 引用...

此假设ID是唯一的,并且不存在周期:例如A的父是B,但B的父是A

Dim dict As Scripting.Dictionary

Function JobRoot(ID As Long) As Long
    If dict Is Nothing Then
        Set dict = New Scripting.Dictionary
        Dim rs As DAO.Recordset
        Set rs = CurrentDb.OpenRecordset("SELECT ID, ParentID FROM Job", dbOpenForwardOnly, dbReadOnly)
        Do Until rs.EOF
            dict(rs!ID) = rs!ParentID
            rs.MoveNext
        Loop
        Set rs = Nothing

        Dim key As Variant
        For Each key In dict.Keys
            Dim possibleRoot As Integer
            possibleRoot = dict(key)
            Do While dict(possibleRoot) <> 0
                possibleRoot = dict(possibleRoot)
            Loop
            dict(key) = possibleRoot
        Next
    End If
    JobRoot = dict(ID)
End Function

Sub Reset() 'This needs to be called to refresh the data
    Set dict = Nothing
End Sub

OK所以这里是真正的交易。首先,什么是目标受众为您查询..一种形式?报告?功能的/ proc?

表:需要更新?使用TreeView控件,而笨拙的它会很好地工作。 报告:在打开的情况下使用的参数形式来设定“老板作业”电平,那么在处理VBA递归和填充一个记录具有期望的顺序中的数据的 即可。报告记录设置为这个充满记录和处理的报告。  功能/过程:工作几乎相同的如上述报告中所述一个的数据负载。通过代码,处理必要的“树行走”,并将结果存储在根据需要一个记录和处理所需的顺序来设置。

泽夫的贡献给了我灵感和学习的很多。然而,需要做一些编辑的代码。请注意,我的表称为“tblTree”。

Dim dict As Scripting.Dictionary

Function TreeRoot(ID As Long) As Long
    If dict Is Nothing Then
        Set dict = New Scripting.Dictionary ' Requires Microsoft Scripting Runtime
        Dim rs As DAO.Recordset
        Set rs = CurrentDb.OpenRecordset("tblTree", dbOpenForwardOnly, dbReadOnly)
        Do Until rs.EOF
            dict.Add (rs!ID), (rs!ParentID)
            rs.MoveNext
        Loop
        Set rs = Nothing
    End If

    TreeRoot = ID

    Do While dict(TreeRoot) <> 0    ' Note: short version for dict.item(TreeRoot)
        TreeRoot = dict(TreeRoot)
    Loop
End Function

和有在相同的上下文中的另一个有用的功能。 “ChildHasParent”返回true,如果孩子在任何嵌套级别的供给PARENTID匹配。

Function ChildHasParent(ID As Long, ParentID As Long) As Boolean
    If dict Is Nothing Then
        Set dict = New Scripting.Dictionary ' Requires Microsoft Scripting Runtime
        Dim rs As DAO.Recordset
        Set rs = CurrentDb.OpenRecordset("tblTree", dbOpenForwardOnly, dbReadOnly)
        Do Until rs.EOF
            dict.Add (rs!ID), (rs!ParentID)
            rs.MoveNext
        Loop
        Set rs = Nothing
    End If

    ChildHasParent = False

    Do While dict(ID) <> 0    ' Note: short version for dict.item(TreeRoot)
        ID = dict(ID)
        If ID = ParentID Then
            ChildHasParent = True
            Exit Do
        End If
    Loop
End Function
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top