是否可以在 Access 中创建递归查询?
题
我有一个 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