我如何将 ADODB.Recordset 存储在一个变量中而不是通过引用?
How can i store ADODB.Recordset in a variable NOT by reference?
我有以下代码
Dim rs,SQL
Dim svrs, prods
Set rs = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * FROM myTable"
rs.Open SQL,conn // conn is the connection variable
svrs = Array(rs("server_name"))
prods = Array(rs("product_name"))
rs.MoveNext
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
和myTable is
的架构
server_name | product_name
--------------------------
svr1 | prod 1
server2 | prod 2
server2 | prod 3
现在网页上的预期结果应该显示 svr1
和 prod 1
,但我得到的是 server2
和 prod 2
。这对我来说表明 rs()
正在发送对 rs
变量的引用,因此,当我去 rs.MoveNext
时,因为我的数组 [0] 只是对 rs()
的引用它们的值也会发生变化,这不利于填充这些数组
我想知道的是如何存储 ADODB.Recordset 使其不通过引用传递
注意:我应该指出,上面的代码只是完整代码的一个示例。在 MoveNext
和 For Each
之间,我然后通过使用循环遍历结果来填充 svrs
和 prods
数组,通过使用 ReDim Preserve
扩展他们动态地。
执行 For Each
时的原始代码给出了关于记录集被删除或在末尾的错误,上面的调试代码显示第一个值甚至不正确。
这是给 .
的人的
原代码是
Dim rs,SQL
Dim svrs, prods, vers
Set rs = Server.CreateObject("ADODB.Recordset")
Set vers = CreateObject("Scripting.Dictionary")
SQL = "SELECT * FROM myTable"
rs.Open SQL,conn
svrs = Array(rs("server_name"))
prods = Array(rs("product_name"))
vers.Add rs("server_name")&"-"&rs("product_name"),rs("version")
rs.MoveNext
Do While NOT rs.EoF
If inArray(svrs,rs("server_name")) = false Then
ReDim Preserve svrs(UBound(svrs) + 1)
svrs(UBbound(svrs)) = rs("sever_name")
End If
If inArray(prods,rs("server_name")) = false Then
ReDim Preserve prods(UBound(prods) + 1)
prods(UBbound(prods)) = rs("sever_name")
End If
vers.Add rs("server_name")&"-"&rs("product_name"),rs("version")
rs.MoveNext
Loop
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
架构为myTable is
key | server_name | product_name | version
---------------------------------------------
1 | svr1 | prod 1 | 1.0.2
2 | server2 | prod 2 | 1.0.1
3 | server2 | prod 3 | 1.0.14
注意:是的,我正在使用服务器和产品 table,并且在最终版本中使用外键,是的,键是主键
想法是像
一样显示数据
| server | server | server |
---------------------------------------------
product | version | version | version |
product | version | version | version |
product | version | version | version |
product | version | version | version |
product | version | version | version |
现在因为我读到 here 将字典放入字典只会放入参考我无法创建一个空的 prods
字典作为填充版本的模板(与缺少版本为空)所以我决定创建 2 个数组 of unique svrs
和 prods
values 然后用作访问复合字典键的循环的基础对于版本。
因为(当时)我不知道如何初始化一个不会在 inArray
上出错的空数组我决定用第一个服务器和产品值创建数组然后循环尽管附加了它们。
完成所有这些之后,我想确保我获得了 svrs
和 prods
的唯一值,所以我执行了循环以输出它们。我得到的错误是
ADODB.Field error '80020009'
Either BOF or EOF is True, or the current record had been deleted. Requested Operation requires a current record
/myFile.asp, line 0
测试以确保它不是我的 Do While
循环我删除了输出循环但我没有收到错误所以我删除了 Do While
循环并放回输出循环怀疑如果 我应该有第一个元素的数组实际上将裁判保持在 rs
并因此解释了我得到的 ADODB 错误,那么我将看不到 table 但是第二个
并且因为我无法从我在工作场所的开发机器上登录 SO 或插入 USB 设备来复制代码我不得不重写它所以我将其写为 Minimal Verifiable Code 在另一台机器上,然后我测试了它并得到了与我期望的相同的错误结果。 Do While
的删除和 table 的更改是为了删除不相关的因素(即我如前所述,我用重写的削减代码得到了相同的错误结果)
您需要做的就是使用字段的 value property 而不是字段本身。
svrs = Array(rs("server_name").Value)
prods = Array(rs("product_name").Value)
由于您没有明确设置数组的大小,因此您需要在向数据添加新记录之前保留数组中的所有先前数据。您可以使用 REDIM PRESERVE:
Dim rs,SQL, counter : counter = 0
Dim svrs()
Dim prods()
Set rs = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * FROM myTable"
'-- since you're only grabbing data from the DB, you don't need to worry about managing cursors, meaning it's more efficient to use set rs = conn.Execute( sql )
set rs = conn.Execute( sql )
do while not rs.EOF
Redim Preserve svrs( counter )
Redim Preserve prods( counter )
svrs( counter ) = rs("server_name")
prods( counter ) = rs("product_name")
rs.MoveNext
loop
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
综上所述,您有 2 个单独的数组而不只是一个二维数组有什么特别的原因吗?如果你只需要一个数组,使用 GetRows 将你的记录集数据转移到一个数组中会容易得多:
set rs = conn.Execute( sql )
dim arr2D = rs.GetRows()
现在,您将所有数据都放在一个数组中,不再需要 2 个不同的数组,并且可以跳过 Do-While 循环。
我有以下代码
Dim rs,SQL
Dim svrs, prods
Set rs = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * FROM myTable"
rs.Open SQL,conn // conn is the connection variable
svrs = Array(rs("server_name"))
prods = Array(rs("product_name"))
rs.MoveNext
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
和myTable is
server_name | product_name
--------------------------
svr1 | prod 1
server2 | prod 2
server2 | prod 3
现在网页上的预期结果应该显示 svr1
和 prod 1
,但我得到的是 server2
和 prod 2
。这对我来说表明 rs()
正在发送对 rs
变量的引用,因此,当我去 rs.MoveNext
时,因为我的数组 [0] 只是对 rs()
的引用它们的值也会发生变化,这不利于填充这些数组
我想知道的是如何存储 ADODB.Recordset 使其不通过引用传递
注意:我应该指出,上面的代码只是完整代码的一个示例。在 MoveNext
和 For Each
之间,我然后通过使用循环遍历结果来填充 svrs
和 prods
数组,通过使用 ReDim Preserve
扩展他们动态地。
执行 For Each
时的原始代码给出了关于记录集被删除或在末尾的错误,上面的调试代码显示第一个值甚至不正确。
这是给
原代码是
Dim rs,SQL
Dim svrs, prods, vers
Set rs = Server.CreateObject("ADODB.Recordset")
Set vers = CreateObject("Scripting.Dictionary")
SQL = "SELECT * FROM myTable"
rs.Open SQL,conn
svrs = Array(rs("server_name"))
prods = Array(rs("product_name"))
vers.Add rs("server_name")&"-"&rs("product_name"),rs("version")
rs.MoveNext
Do While NOT rs.EoF
If inArray(svrs,rs("server_name")) = false Then
ReDim Preserve svrs(UBound(svrs) + 1)
svrs(UBbound(svrs)) = rs("sever_name")
End If
If inArray(prods,rs("server_name")) = false Then
ReDim Preserve prods(UBound(prods) + 1)
prods(UBbound(prods)) = rs("sever_name")
End If
vers.Add rs("server_name")&"-"&rs("product_name"),rs("version")
rs.MoveNext
Loop
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
架构为myTable is
key | server_name | product_name | version
---------------------------------------------
1 | svr1 | prod 1 | 1.0.2
2 | server2 | prod 2 | 1.0.1
3 | server2 | prod 3 | 1.0.14
注意:是的,我正在使用服务器和产品 table,并且在最终版本中使用外键,是的,键是主键
想法是像
一样显示数据 | server | server | server |
---------------------------------------------
product | version | version | version |
product | version | version | version |
product | version | version | version |
product | version | version | version |
product | version | version | version |
现在因为我读到 here 将字典放入字典只会放入参考我无法创建一个空的 prods
字典作为填充版本的模板(与缺少版本为空)所以我决定创建 2 个数组 of unique svrs
和 prods
values 然后用作访问复合字典键的循环的基础对于版本。
因为(当时)我不知道如何初始化一个不会在 inArray
上出错的空数组我决定用第一个服务器和产品值创建数组然后循环尽管附加了它们。
完成所有这些之后,我想确保我获得了 svrs
和 prods
的唯一值,所以我执行了循环以输出它们。我得到的错误是
ADODB.Field error '80020009'
Either BOF or EOF is True, or the current record had been deleted. Requested Operation requires a current record
/myFile.asp, line 0
测试以确保它不是我的 Do While
循环我删除了输出循环但我没有收到错误所以我删除了 Do While
循环并放回输出循环怀疑如果 我应该有第一个元素的数组实际上将裁判保持在 rs
并因此解释了我得到的 ADODB 错误,那么我将看不到 table 但是第二个
并且因为我无法从我在工作场所的开发机器上登录 SO 或插入 USB 设备来复制代码我不得不重写它所以我将其写为 Minimal Verifiable Code 在另一台机器上,然后我测试了它并得到了与我期望的相同的错误结果。 Do While
的删除和 table 的更改是为了删除不相关的因素(即我如前所述,我用重写的削减代码得到了相同的错误结果)
您需要做的就是使用字段的 value property 而不是字段本身。
svrs = Array(rs("server_name").Value)
prods = Array(rs("product_name").Value)
由于您没有明确设置数组的大小,因此您需要在向数据添加新记录之前保留数组中的所有先前数据。您可以使用 REDIM PRESERVE:
Dim rs,SQL, counter : counter = 0
Dim svrs()
Dim prods()
Set rs = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT * FROM myTable"
'-- since you're only grabbing data from the DB, you don't need to worry about managing cursors, meaning it's more efficient to use set rs = conn.Execute( sql )
set rs = conn.Execute( sql )
do while not rs.EOF
Redim Preserve svrs( counter )
Redim Preserve prods( counter )
svrs( counter ) = rs("server_name")
prods( counter ) = rs("product_name")
rs.MoveNext
loop
For Each item In svrs
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
For Each item In prods
Response.Write item
Response.Write "<br>"
Next
Response.Write "<br>"
综上所述,您有 2 个单独的数组而不只是一个二维数组有什么特别的原因吗?如果你只需要一个数组,使用 GetRows 将你的记录集数据转移到一个数组中会容易得多:
set rs = conn.Execute( sql )
dim arr2D = rs.GetRows()
现在,您将所有数据都放在一个数组中,不再需要 2 个不同的数组,并且可以跳过 Do-While 循环。