【问题标题】:Having a BOF or EOF error, after call recordCount调用 recordCount 后出现 BOF 或 EOF 错误
【发布时间】:2012-10-18 16:30:08
【问题描述】:

我必须调用recordCount 函数来获取记录集的计数。 但是一旦我调用recordCount 函数,记录集就失控了。

...
Dim objRootDSE, strDNSDomain, adoCommand, adoConnection
Set adoCommand = CreateObject("ADODB.Command")
'Set adoRecordset = adoCommand.Execute
Set adoRecordset = Server.CreateObject ("ADODB.Recordset") 
adoRecordset.cursorType = 3
adoRecordset.CursorLocation = adUseClient 
adoRecordset = adoCommand.Execute
...


totalcnt = adoRecordset.recordCount

If totalcnt > 0 Then 
...
    Do until adoRecordset.EOF
        ' Retrieve values... But it fails because it seems adoRecordset is in EOF
        ...

所以我使用movefirst 并尝试检索值。

If adoRecordset.recordCount > 0 Then 
                                            adoRecordset.movefirst
    ...

但出现错误(以下由google翻译)

ADODB.Recordset 오류 '800a0bcd' 
BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.

如果我不打电话给recordCount,就没有问题。但我应该知道记录的数量。

整个代码是:

    <%
'On Error Resume next
 Dim objRootDSE, strDNSDomain, adoCommand, adoConnection
 Dim strBase, strFilter, strAttributes, strQuery, adoRecordset
 Dim strDN, strUser, strPassword, objNS, strServer
 Dim name,company,physicalDeliveryOfficeName

 Const ADS_SECURE_AUTHENTICATION = 1
 Const ADS_SERVER_BIND = 0

 ' Specify a server (Domain Controller).
 strServer = "my_ad_server_domain"

 ' Specify or prompt for credentials.
 strUser = "my_account"
 strPassword = "my_passwrd"

 ' Determine DNS domain name. Use server binding and alternate
 ' credentials. The value of strDNSDomain can also be hard coded.
 Set objNS = GetObject("LDAP:")
 Set objRootDSE = objNS.OpenDSObject("LDAP://" & strServer & "/RootDSE", _
      strUser, strPassword, _
      ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION)
 strDNSDomain = objRootDSE.Get("defaultNamingContext")

 ' Use ADO to search Active Directory.
 ' Use alternate credentials.
 Set adoCommand = CreateObject("ADODB.Command")
 Set adoConnection = CreateObject("ADODB.Connection")
 adoConnection.Provider = "ADsDSOObject"
 adoConnection.Properties("User ID") = strUser
 adoConnection.Properties("Password") = strPassword
 adoConnection.Properties("Encrypt Password") = True
 adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND _
      Or ADS_SECURE_AUTHENTICATION
 adoConnection.Open "Active Directory Provider"
 Set adoCommand.ActiveConnection = adoConnection

 ' Search entire domain. Use server binding.
 strBase = "<LDAP://" & strServer & "/" & strDNSDomain & ">"

 ' Search for all users.
 strFilter = "(&(objectCategory=user)(ExADObjectStatus=10)(samaccountname=*"&"my_search_value"&"*))"

 ' Comma delimited list of attribute values to retrieve.
 strAttributes = "name,company,physicalDeliveryOfficeName"

 ' Construct the LDAP query.
 strQuery = strBase & ";" & strFilter & ";" _
      & strAttributes & ";subtree"

 ' Run the query.
 adoCommand.CommandText = strQuery
 adoCommand.Properties("Page Size") = 100
 adoCommand.Properties("Timeout") = 60
 adoCommand.Properties("Cache Results") = False
 Set adoRecordset = adoCommand.Execute




if not adoRecordset.EOF then 
    totalcnt = adoRecordset.recordCount 
    If totalcnt > 0 Then  
    Response.write 111
        Do until adoRecordset.EOF
            name = adoRecordset.Fields("name").Value
              company = adoRecordset.Fields("company").Value
              physicalDeliveryOfficeName = adoRecordset.Fields("physicalDeliveryOfficeName").Value
              Response.Write name & "<br/>"
              Response.Write company & "<br/>"
              Response.Write physicalDeliveryOfficeName
              adoRecordset.MoveNext
        Loop 
    end if 
end if 



 ' Clean up.
 adoRecordset.Close
 adoConnection.Close 
%>

只显示一个记录结果。

【问题讨论】:

    标签: asp-classic vbscript


    【解决方案1】:

    您可以尝试从不同的角度面对问题。与其尝试修复内部 recordCount 属性(您不能),不如自己计算记录:

    totalcnt = 0
    Do until adoRecordset.EOF
        totalcnt = totalcnt + 1
        adoRecordset.MoveNext
    Loop
    
    If totalcnt>0 Then
        adoRecordset.MoveFirst
        Do until adoRecordset.EOF
            name = adoRecordset.Fields("name").Value
            '...
            adoRecordset.MoveNext
        Loop
    End If
    

    更新:看起来在这种特定情况下,MoveFirst 只是失败了,可能是因为它是 LDAP 而不是来自数据库的普通查询。为了一劳永逸地解决这个问题,您可以在迭代记录时填充自己的集合,然后尽可能多地使用该集合:

    Dim oData, oField, tempArray
    Set oData = Server.CreateObject("Scripting.Dictionary")
    totalcnt = 0
    For Each oField In adoRecordset.Fields
        oData.Add oField.Name, Array()
    Next
    Do until adoRecordset.EOF
        For Each oField In adoRecordset.Fields
            tempArray = oData(oField.Name)
            ReDim Preserve tempArray(UBound(tempArray) + 1)
            tempArray(UBound(tempArray)) = oField.Value
            oData(oField.Name) = tempArray
        Next
        totalcnt = totalcnt + 1
        adoRecordset.MoveNext
    Loop
    adoRecordset.Close
    
    Dim x
    If totalcnt>0 Then
        Response.Write("found total of " & totalcnt & " records<br />")
        For x=0 To totalcnt-1
            name = oData("name")(x)
            company = oData("company")(x)
            physicalDeliveryOfficeName = oData("physicalDeliveryOfficeName")(x)
            Response.Write name & "<br/>"
            Response.Write company & "<br/>"
            Response.Write physicalDeliveryOfficeName
        Next
    End If
    

    【讨论】:

    • 多么聪明的解决方案!我试过你的建议,但它不起作用。 moveFirst 似乎在我的 IIS 6.0 中不起作用。我认为我的服务器有一些配置问题或我无法找到的问题。
    • 你的意思是“不起作用”?当你有MoveFirst 行时会发生什么?
    • 当你有Response.Write("count: " &amp; totalcnt &amp; "&lt;br /&gt;")你会得到什么?
    • 显示正常结果count: 13。我将该代码添加到Do until adoRecordset.EOF 的循环中,但它没有出来。
    • @Deckard 很奇怪。看我的编辑,这将 99% 的工作,虽然它可能有点矫枉过正。
    【解决方案2】:

    如错误所示,如果记录集中没有记录,则recordCount 失败。

    您可以在代码块之前对此进行测试。试试这个:

    if not adoRecordset.EOF then
        totalcnt = adoRecordset.recordCount
        If totalcnt > 0 Then 
            ...
            Do while not adoRecordset.EOF
            ...
            Loop
        end if
    end if
    

    edit:更正循环以测试 not adoRecordset.eof

    【讨论】:

    • 这样更好,但它只显示一个记录集的结果。原始代码为do until。我犯了一个错误。
    • @Deckard 好的,我没有注意到在 do while adoRecordset.EOF... 上测试的循环应该是 Do while not adoRecordset.EOF(或 Do until ..)顺便说一句,你还需要你的totalcnt吗?您可以用 adoRecordset.EOF 上的测试替换 totalcnt
    • 您的记录数大于那个?你的循环中有 movenext 吗?
    • 是的,我做到了。我会将整个代码添加到我的问题中。谢谢你。我刚刚添加了。
    • 代码对我来说看起来不错。我会跳过对 recordCount 的检查(并使用对 adoRecordset.oef 的检查)。不知道为什么你只看到一行.. 也许 ldap 查询已经将你定位在最后一条记录,而不是添加 adoRecordset.movefirst before Do while 循环
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多