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

Asp classic 将断开连接的记录集插入字典对象?,asp-classic,Asp Classic,只是想知道是否有人看到过这个问题,当尝试将断开连接的记录集中的项插入到经典ASP dictionary对象中时,我得到错误“此键已与此集合的元素关联” 事实并非如此,所有关键元素都是唯一的,是的,我对数据进行了三次检查:) 如果我将数据放入局部变量,它就可以正常工作(参见下面的代码)。虽然我对此没意见,但有没有其他人看到过这个问题,或者知道它为什么不起作用 Set Options=Server.CreateObject(“Scripting.Dictionary”) 功能填充(ID)'工作 Di

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

事实并非如此,所有关键元素都是唯一的,是的,我对数据进行了三次检查:)

如果我将数据放入局部变量,它就可以正常工作(参见下面的代码)。虽然我对此没意见,但有没有其他人看到过这个问题,或者知道它为什么不起作用

Set Options=Server.CreateObject(“Scripting.Dictionary”)
功能填充(ID)'工作
Dim strsql、rs、名称、id
如果Options.Count=0,则
strsql=“从选项where unique=“&SafeSQL(ID)中选择名称、ID”
Set rs=RunSQLReturnRS(strsql,null,“Populate”)'返回断开连接的记录集
做而不做
名称=卢比(“名称”)
id=rs(“id”)
选项。添加名称、id
下一个
环
克洛斯
如果结束
端函数
函数Populate2(ID)“”不起作用
Dim strsql,rs
如果Options.Count=0,则
strsql=“从选项where unique=“&SafeSQL(ID)中选择名称、ID”
Set rs=RunSQLReturnRS(strsql,null,“Populate”)'返回断开连接的记录集
做而不做
选项。添加rs(“名称”)、rs(“id”)
下一个
环
克洛斯
如果结束
端函数
根据用户影子向导的请求,断开连接的记录函数(注意my_conn是数据库连接,在调用此函数时已打开)

函数RunSQLReturnRS(sqlstmt,params(),fromfunction)
“”//创建ADO对象
Dim rs,cmd
Set rs=server.createobject(“ADODB.Recordset”)
如果不是zerolength(sqlstmt),则
Set cmd=server.createobject(“ADODB.Command”)
''//Init ADO对象和存储的过程参数
cmd.ActiveConnection=my\u conn
cmd.CommandText=sqlstmt
cmd.CommandType=adCmdText
cmd.CommandTimeout=900
''//propietary函数,将参数放入cmd
collectParams cmd,params
''//执行只读查询
rs.CursorLocation=adUseClient
出错时继续下一步
rs.Open cmd、adOpenForwardOnly、adLockReadOnly
如果错误号为0,则Response.write“Error:&Err.Description&”
fromfonment=“&fromfonment&”
”:Response.end 错误转到0 ''//断开记录集的连接 Set cmd.ActiveConnection=Nothing Set cmd=Nothing 设置rs.ActiveConnection=Nothing 如果结束 ''//返回结果记录集 设置RunSQLReturnRS=rs 端函数
好的,这有点棘手,但我知道发生了什么

VBScript字典对象的
Add()
方法正在接受一个对象作为键参数和值参数。此对象可以是任何类型:数字、字符串、日期、复杂类型等

不为人所知的是,当您编写“rs”属于记录集类型的
rs(“name”)
时,它不会返回基元类型,而是返回一个字段对象

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

当你有这个:

name = rs("name")
它实际上意味着:

name = rs("name").Value
因此,在第一个方法中,将字符串作为键,一切都很好。在第二种方法中,传递字段对象本身,而VBScript在字段对象之间缺乏适当的比较机制,因此它认为它们都是相同的

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

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

我想是因为在第二个示例中,您插入了对字段的引用。这就是为什么它不适用于断开连接的db。我首先对插入值进行采样(我也总是这样做)。对于记录,这不是一个断开连接的记录集。这是一个现场录音集。断开连接的记录集是指您自己从头创建(而不是从数据库创建)并手动添加字段和值的记录集。只是语义,但想让您知道您使用了错误的术语。:)似乎有点奇怪,它与数据源“断开连接”,如何获取数据应该无关紧要,我会转储活动连接。。。。也许我应该称它为僵尸记录集:),但你不是在断开它的连接,只是使用一个函数来返回它。没有重复键,请看代码,你会看到它在两个示例中使用相同的数据,第二个函数可以很好地处理完全相同的内容,唯一不同的是,我首先将字典数据放入局部变量,然后再将其插入字典。这是一条错误消息(它不应该出错),甚至是ASP中的一个错误。请自行测试。我已根据我的要求添加了RunSqlReturns函数。对不起,西尔弗,我错了。由于它仍然是新鲜的,我冒昧地彻底改变了答案,使其正确,请看它现在。实际上没有测试它自己,所以希望我没有完全错在这里。。。让我知道它是否真的有效。好的,这是一次很好的尝试,看起来很合乎逻辑。我刚刚测试过,恐怕不能解决问题。如果我使用rs(“id”).value(例如),我会得到一个类型不匹配错误,这真的很奇怪。
do while not rs.eof
    Options.Add rs("name").Value, rs("id").Value
    rs.movenext
loop