我正在研究自90年代以来一直在使用的系统。用VB6编写,最初设置为使用Access数据库和JET驱动程序。
现在,由于我们的客户端在Access数据库上遇到2GB文件大小限制,我们正在考虑将所有内容转换为mySQL。
不幸的是,大约5年前编写的系统中的所有内容都使用了这种逻辑:
Dim rst As New ADODB.Recordset
rst.ActiveConnection = cnn
rst.Open "table"
rst.Index = "index"
rst.Seek Array("field1", "field2"), adSeekFirstEQ
rst!field1 = "something new"
rst.Update
较新的代码使用的是SELECT
,UPDATE
等SQL命令。
所以,我们希望做的是为我们的客户提供新的mySQL数据库 - 让他们进行数据库设置,但使用所有旧代码。
问题是我在使用SQL数据库时无法使用Index
......除此之外,其他一切似乎都能正常工作。
我收到错误:#3251: Current provider does not support the necessary interface for Index functionality.
有什么我想念的吗?在使用SQL时是否有另一种方法来Seek
这样我可以按索引进行排序?或者我是否必须进入并更改整个系统并删除所有Seek
逻辑 - 这已经使用了几千次?这对于我们所有的报告来说尤其是一个问题,我们可能会有一个带有索引的表,其中Col 1被排序为ASC,Col 2被排序为DESC,Col 3再次是ASC,我需要找到前{5个记录{{1 }}。你还怎么做呢?
答案 0 :(得分:1)
谁想使用VB6?尽管如此...
如果未指定Provider,则无法使用Index属性。据我所知只有MS Jet的OleDb支持* Seek *方法和* 索引 *属性。 请阅读:
寻求方法 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms675109%28v=vs.85%29.aspx
索引属性 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms675255%28v=vs.85%29.aspx
ConnectionString 属性 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms675810%28v=vs.85%29.aspx
提供商属性 - http://msdn.microsoft.com/en-us/library/windows/desktop/ms675096%28v=vs.85%29.aspx
有关详细信息,请参阅:http://msdn.microsoft.com/en-us/library/windows/desktop/ms681510%28v=vs.85%29.aspx
<强> [编辑] 强>
你的意见后...
我强烈建议强调download and install Visual Studio Express Edition并使用VB.NET代替VB6。比安装ADO.NET MySQL Connector并重新编写应用程序,使用最新技术而不是用ADODB对象折磨自己等。
例子:
Connecting to MySQL databases using VB.NET
的 [/编辑] 强>
答案 1 :(得分:1)
因为,正如你发布的那样,数据库不支持Seek或Index,就你而言,你有点不走运。
但是,如果你真的 必须 使用seek / index我建议将SQL查询的结果导入到本地.mdb文件中,然后使用它来制作记录集的工作方式与其他代码一样 从性能的角度来看,这有点恶劣,老实说,从长远来看,替换所有的搜索和索引调用可能会更好,但至少它会节省你编码的时间。
要创建本地数据库,您可以执行以下操作:
Function dimdbs(Temptable as String)
Dim tdfNew As TableDef
Dim prpLoop As Property
Dim strDbfullpath As String
Dim dbsn As Database
Dim idx As Index
Dim autofld As Field
'PARAMETERS: DBFULLPATH: FileName/Path of database to create
strDbfullpath = VBA.Environ$("TMP") & "\mydb.mdb"
If Dir(strDbfullpath) <> "" Then
Set dbsn = DBEngine.Workspaces(0).OpenDatabase(strDbfullpath)
Else
Set dbsn = DBEngine.CreateDatabase(strDbfullpath, dbLangGeneral)
End If
Set tdfNew = dbsn.CreateTableDef(Temptable)
With tdfNew
' Create fields and append them to the new TableDef
' object. This must be done before appending the
' TableDef object to the TableDefs collection of the
' database.
Set autofld = .CreateField("autonum", dbLong)
autofld.Attributes = dbAutoIncrField
.Fields.Append autofld
.Fields.Append .CreateField("foo", dbText, 3)
.Fields.Append .CreateField("bar", dbLong)
.Fields.Append .CreateField("foobar", dbText, 30)
.Fields("foobar").AllowZeroLength = True
Set idx = .CreateIndex("PrimaryKey")
idx.Fields.Append .CreateField("autonum")
idx.Unique = True
idx.Primary = True
.Indexes.Append idx
Debug.Print "Properties of new TableDef object " & _
"before appending to collection:"
' Enumerate Properties collection of new TableDef
' object.
For Each prpLoop In .Properties
On Error Resume Next
If prpLoop <> "" Then Debug.Print " " & _
prpLoop.Name & " = " & prpLoop
On Error GoTo 0
Next prpLoop
' Append the new TableDef object to the Northwind
' database.
If ObjectExists("Table", Temptable & "CompletedCourses", "Userdb") Then
dbsn.Execute "Delete * FROM " & Temptable & "CompletedCourses"
Else
dbsn.TableDefs.Append tdfNew
End If
Debug.Print "Properties of new TableDef object " & _
"after appending to collection:"
' Enumerate Properties collection of new TableDef
' object.
For Each prpLoop In .Properties
On Error Resume Next
If prpLoop <> "" Then Debug.Print " " & _
prpLoop.Name & " = " & prpLoop
On Error GoTo 0
Next prpLoop
End With
Set idx = Nothing
Set autofld = Nothing
End Function
稍后查找并删除它,您可以使用以下内容:
Function DeleteAllTempTables(strTempString As String, Optional tmpdbname As String = "\mydb.mdb", Optional strpath As String = "%TMP%")
Dim dbs2 As Database
Dim t As dao.TableDef, I As Integer
Dim strDbfullpath
If strpath = "%TMP%" Then
strpath = VBA.Environ$("TMP")
End If
strDbfullpath = strpath & tmpdbname
If Dir(strDbfullpath) <> "" Then
Set dbs2 = DBEngine.Workspaces(0).OpenDatabase(strDbfullpath)
Else
Exit Function
End If
strTempString = strTempString & "*"
For I = dbs2.TableDefs.Count - 1 To 0 Step -1
Set t = dbs2.TableDefs(I)
If t.Name Like strTempString Then
dbs2.TableDefs.Delete t.Name
End If
Next I
dbs2.Close
End Function
要从SQL导入到该DB,您必须获取记录集并使用for循环添加每个记录(除非它是固定的ODBC连接,我认为您可以直接导入但我没有示例代码)
Dim formrst As New ADODB.recordset
Set mysqlconn = New ADODB.Connection
Dim dbsRst As recordset
Dim dbs As Database
'opens the ADODB connection to my database
Call openConnect(mysqlconn)
'calls the above function to create the temp database
'Temptable is defined as a form-level variable so it can be unique to this form
'and other forms/reports don't delete it
Call dimdbs(Temptable)
Me.RecordSource = "SELECT * FROM [" & Temptable & "] IN '" & VBA.Environ$("TMP") & "\mydb.mdb'"
Set dbs = DBEngine.Workspaces(0).OpenDatabase(VBA.Environ$("TMP") & "\mydb.mdb")
Set dbsRst = dbs.OpenRecordset(Temptable)
Set formrst.ActiveConnection = mysqlconn
Call Selectquery(formrst, strSQL & strwhere & SQLorderby, adLockReadOnly, adOpenForwardOnly)
With formrst
Do Until .EOF
dbsRst.AddNew
dbsRst!foo = !foo
dbsRst!bar = !bar
dbsRst!foobar = !foobar
dbsRst.Update
.MoveNext
Loop
.Close
End With
dbsRst.Close
Set dbsRst = Nothing
dbs.Close
Set formrst = Nothing
您必须在保存时或最后关闭的表单上重新导入数据,但至少只需要一个SQL语句,或者您可以直接使用ODBC连接。
这远远不是最佳的,但至少你可以将所有这些代码放在一两个额外的函数调用中,它不会干扰原始逻辑。
我必须对Allen Browne给予高度评价,我从所有地方提取此代码,但我的大多数代码可能来自或受到其网站的启发(http://allenbrowne.com/)