微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp-classic – 将断开连接的记录集插入字典对象?

只是想知道是否有人看到过这个问题,当试图将断开连接的记录集中的项目插入到经典的ASP字典对象中时,我得到错误“此密钥已经与此集合的元素相关联”.

事实并非如此,所有关键元素都是独一无二的,是的,我三重检查数据:)

如果我将数据推送到局部变量,它工作正常(见下面的代码).虽然我没关系,但还有其他人看过这个问题,或者知道为什么它不起作用?

Set Options=Server.CreateObject("Scripting.Dictionary")

function Populate(ID) ' WORKS
    Dim strsql,rs,name,id
    if Options.Count = 0 then
        strsql = "select name,ID from options where unique = " & Safesql(ID)
        Set rs = RunsqlReturnRS(strsql,null,"Populate") ' returns a disconnected recordset
        do while not rs.eof
            name = rs("name")
            id = rs("id")
            Options.Add name,id
            rs.movenext
        loop
        rs.close
    end if
end function

function Populate2(ID) ' DOES NOT WORK
    Dim strsql,rs
    if Options.Count = 0 then
        strsql = "select name,"Populate") ' returns a disconnected recordset
        do while not rs.eof
            Options.Add rs("name"),rs("id")
            rs.movenext
        loop
        rs.close
    end if
end function

根据用户Shadow Wizard的请求,断开连接的记录功能,(注意my_conn是数据库连接,并且在调用函数时已经打开)

Function RunsqlReturnRS(sqlstmt,params(),fromfunction)
    ''//Create the ADO objects
    Dim rs,cmd

    Set rs = server.createobject("ADODB.Recordset")
    If Not zerolength(sqlstmt) then
      Set cmd = server.createobject("ADODB.Command")

      ''//Init the ADO objects  & the stored proc parameters
      cmd.ActiveConnection = my_conn
      cmd.CommandText = sqlstmt
      cmd.CommandType = adCmdText
      cmd.CommandTimeout = 900

      ''// propietary function that put params in the cmd
      collectParams cmd,params

      ''//Execute the query for readonly
      rs.CursorLocation = adUseClient
      On Error Resume Next
        rs.Open cmd,adOpenForwardOnly,adLockReadOnly
        If Err.Number <> 0 Then Response.write "Error: "&Err.Description & "<br>fromfunction=" & fromfunction & "<br>" : Response.end
      On Error Goto 0
      ''// disconnect the recordset
      Set cmd.ActiveConnection = nothing
      Set cmd = nothing
      Set rs.ActiveConnection = nothing
    End if
    ''// Return the resultant recordset
    Set RunsqlReturnRS = rs
  End Function

解决方法

好吧,这有点棘手但我知道发生了什么.

VBScript Dictionary对象的Add()方法接受键和值参数的Object.该对象可以是任何类型:数字,字符串,日期,复杂类型等.

不常见的是当你写rs(“name”),其中“rs”是Recordset类型时,它不返回基本类型,而是返回一个Field对象.

但是,如果您尝试将其分配给局部变量,则VBScript足够智能以查找该对象的属性,如果存在,则执行它. Field对象确实有这样的属性,它返回字段的Value.

当你有这个:

name = rs("name")

它实际上意味着:

name = rs("name").Value

所以在你的第一个方法中,你给一个字符串作为键,一切都很好.在第二种方法中,您传递Field对象本身,并且VBScript在Field对象之间缺少适当的比较机制,因此它认为它们都是相同的.

要使第二个方法在不使用局部变量的情况下工作,请将其更改为:

do while not rs.eof
    Options.Add rs("name").Value,rs("id").Value
    rs.movenext
loop

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐