VBScript 中的 MoveFirst 不适用于查询上的查询?

发布于 2025-01-09 06:30:16 字数 1630 浏览 5 评论 0原文

我有一段 VBScript 可以查询 MS Access 数据库。当记录集查询位于表上时,我可以浏览记录集并执行 rs.MoveFirst 返回到开头。但是当记录集查询在查询上时,rs.MoveFirst 失败并出现错误“此类型的对象不支持操作”代码:800004005。
这是一个已知的限制吗?我可以通过以不同的方式打开记录集来解决这个问题吗? 我已经像网上的许多例子一样尝试了 rs.Open,但是 rs.Open strQuery, Cn, adOpenDynamic, adLockPessimistic, adCmdText 失败,并显示“参数类型错误,超出可接受的范围,或者在可接受的范围内”彼此发生冲突。”

此代码有效,因为 MyTable 是一个表:

Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
Set rs = connection.Execute("SELECT * FROM MyTable")

MsgBox(rs.fields(1))
rs.MoveNext
rs.MoveFirst
MsgBox(rs.fields(1))

此代码失败,因为 MyQuery 是数据库中的查询

Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
Set rs = connection.Execute("SELECT * FROM MyQuery")

MsgBox(rs.fields(1))
rs.MoveNext
rs.MoveFirst
MsgBox(rs.fields(1))

使用 rs.Open 并定义常量不起作用。这在 rs.movefirst 命令上显示相同的错误“此类型的对象不支持操作”。

const adOpenDynamic = 2
const adLockPessimistic = 2
const adCmdText = 1

Set connection = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
strsql = "SELECT * FROM MyQuery"
rs.Open strsql, connection, adOpenDynamic, adLockPessimistic, adCmdText

Do While Not rs.EOF
    msgbox(rs.fields(1))
    rs.movenext
    msgbox(rs.fields(1))
    rs.movefirst
    msgbox(rs.fields(1))
Loop

I have a piece of VBScript that queries an MS Access database. When the recordset query is on a table, I can go through my recordset and do a rs.MoveFirst to go back to the beginning. But when the recordset query is on a query, rs.MoveFirst fails with the error "Operation is not supported for this type of object" Code: 800004005.
Is this a known limitation? Can I get get around it by opening the recordset in a different way?
I have tried rs.Open like many examples online, but rs.Open strQuery, Cn, adOpenDynamic, adLockPessimistic, adCmdText fails with "Arguments are of the wront type, are out of acceptable range, or are in conflict with one another."

This code works because MyTable is a table:

Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
Set rs = connection.Execute("SELECT * FROM MyTable")

MsgBox(rs.fields(1))
rs.MoveNext
rs.MoveFirst
MsgBox(rs.fields(1))

This code fails because MyQuery is a query in the database

Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
Set rs = connection.Execute("SELECT * FROM MyQuery")

MsgBox(rs.fields(1))
rs.MoveNext
rs.MoveFirst
MsgBox(rs.fields(1))

Using rs.Open and defining the constants does not work. This shows the same error "Operation is not supported for this type of object" on the rs.movefirst command.

const adOpenDynamic = 2
const adLockPessimistic = 2
const adCmdText = 1

Set connection = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
connection.Open strConnection
strsql = "SELECT * FROM MyQuery"
rs.Open strsql, connection, adOpenDynamic, adLockPessimistic, adCmdText

Do While Not rs.EOF
    msgbox(rs.fields(1))
    rs.movenext
    msgbox(rs.fields(1))
    rs.movefirst
    msgbox(rs.fields(1))
Loop

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花落人断肠 2025-01-16 06:30:16

有一种更简单的方法来处理这个问题,那就是完全否定 ADODB.Recordset 并且不必担心游标和锁定支持。值得一提的是,这仅适用于读取数据。

使用 GetRows() 检索二维数组并使用它来导航数据。

Dim strConnection, connection, rs, data
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
Call connection.Open(strConnection)
Set rs = connection.Execute("SELECT * FROM MyTable")
If Not rs.EOF Then data = rs.GetRows()

'Release recordset as it's no longer needed.
Call rs.Close()
Set rs = Nothing

Dim row, rows
Const fld_field1 = 1

If IsArray(data) Then
    rows = UBound(data, 2) 'Number of rows
    row = 0 
    Call MsgBox(data(fld_field1, row) 'Second column of First Row
    row = 1
    Call MsgBox(data(fld_field1, row) 'Second column of Second Row
    row = 0
    Call MsgBox(data(fld_field1, row) 'Second column of First Row

    'If you want to loop the data
    For row = 0 To rows
        Call MsgBox(data(1, row) 'Second Column of N Row
    Next
End If

There is a far easier way to deal with this problem and that is to negate ADODB.Recordset entirely and not have to worry about cursor and locking support. It's worth mentioning this will only work for reading the data.

Use GetRows() to retrieve a two-dimensional Array and use that to navigate the data.

Dim strConnection, connection, rs, data
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
Call connection.Open(strConnection)
Set rs = connection.Execute("SELECT * FROM MyTable")
If Not rs.EOF Then data = rs.GetRows()

'Release recordset as it's no longer needed.
Call rs.Close()
Set rs = Nothing

Dim row, rows
Const fld_field1 = 1

If IsArray(data) Then
    rows = UBound(data, 2) 'Number of rows
    row = 0 
    Call MsgBox(data(fld_field1, row) 'Second column of First Row
    row = 1
    Call MsgBox(data(fld_field1, row) 'Second column of Second Row
    row = 0
    Call MsgBox(data(fld_field1, row) 'Second column of First Row

    'If you want to loop the data
    For row = 0 To rows
        Call MsgBox(data(1, row) 'Second Column of N Row
    Next
End If
仄言 2025-01-16 06:30:16

这会起作用。
你不需要声明 const、变量等等。
您只需设置对 ADODB 的引用,在您的情况下是对 Microsoft Activex Data Objects 2.8 Library 的引用。
没有理由这行不通。

Set Connection = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Dim strConnection
Dim sql

strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
Connection.Open strConnection

sql = "SELECT * FROM MyQuery"

rs.Open sql, Connection, adOpenStatic, adLockReadOnly, adCmdText

MsgBox (rs.Fields(1))
rs.MoveNext
MsgBox (rs.Fields(1))
rs.MoveFirst
MsgBox (rs.Fields(1))

rs.Close
Set rs = Nothing
Connection.Close
Set Connection = Nothing

编辑:我忽略了你写的“一段vbscript”这一事实。如果您在 vbs 文件中使用此代码,则需要声明常量

Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adCmdText = &H0001

This will work.
You don't need to declare const, variables, whatelse.
You just need to set a reference to ADODB, in your case a reference to Microsoft Activex Data Objects 2.8 Library.
There is no reason this would not work.

Set Connection = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
Dim strConnection
Dim sql

strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\MyAccessDB.accdb;Mode=Read;"
Connection.Open strConnection

sql = "SELECT * FROM MyQuery"

rs.Open sql, Connection, adOpenStatic, adLockReadOnly, adCmdText

MsgBox (rs.Fields(1))
rs.MoveNext
MsgBox (rs.Fields(1))
rs.MoveFirst
MsgBox (rs.Fields(1))

rs.Close
Set rs = Nothing
Connection.Close
Set Connection = Nothing

EDIT: I overlooked the fact you wrote "piece of vbscript". If you are using this code in a vbs file, then you need to declare the constants

Const adOpenStatic = 3
Const adLockReadOnly = 1
Const adCmdText = &H0001
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文