赞
踩
VB作为一个高效快捷的开发工具而言,在数据库开发上有着很好的表现。但是,对于很多初学者而言,入门时经常会看一些并非高效且封装得更加多的代码作为学习参考(如那种用什么控件、数据捆绑之类的范例代码),导致很多多初学者想深入时会更加茫然。其实,曾经很多用VB开发的数据库商用软件都不会用那种方法,因为弊病很多,效率也不高。先总结一下为什么说用数据控件效率不高。首先,作为数据库操作的对象而言,是不需要有用户界面的,完全可以在后来默默的查询数据供开发者在代码里任意使用,而控件,其实就是一个用窗口封装的代码模块,里面除了对接数据查询功能,还花了不少代码去搞窗口消息的处理和重绘之类的,当然除了浪费内存,还浪费CPU去处理那些窗口代码,与单纯的无界面后台操作数据库的方式而言,控件的效率肯定要打折扣,还有一个问题就是多窗口使用同一个数据库时,处理起来也很麻烦。再说说那种捆绑数据自动显示的弊病和问题吧。首先因为捆绑了数据源的控件都是自行去分析捆绑记录集的字段、类型、数据条数等,并根据数据源的触发事件将其需要显示的信息自动显示在数据表或输入框中,那么就意味着这些控件都有通过消息或管道进行侦听监控才触发的这些更新过程,这无形中又会浪费很多内存资源和CPU资源,效率肯定也会下降。再者就是灵活性差,因为他是根据记录集查询出来的内容变化整体输出或单条输出,而不是通过代码控制处理,碰到些想合并表格或做点表格表达式运算处理就有心无力了。所以,通常专业的商用软件很少有人会用这种数据控件或数据捆绑技术作为数据库操作的核心处理模式。那么我所谓的专业的商用软件具体用的是什么技术去实现这种数据库操作的呢?其实对于看了众多案例的初学者来说应该也可能见过,就是使用 ADO 对象,全称是 Microsoft ActiveX Data Objects,在VB引用里可以找到,不过你可能找到的有很多版本,如:
具体选哪一个呢,其实都可以,保险点选个最低版本都兼容,当你勾选了一个ADO对象后选确定,然后点击“对象浏览器”按钮,然后再点开对象下拉列表,就可以看到一个新的对象 ADODB在你的工程中了,如:
这时我们可以鼠标右键点击Form1窗口,在弹出的菜单选“查看代码”编辑些初始代码。
而在编写代码前,我先介绍一下 ADO 对象,ADO 对象主要是负责与数据引擎对接的一个公共接口。其中比较常用的有两个部分,一个是链接对象 ADODB.Connection 和记录集 ADODB.Recordset,然后我再分别介绍一下这两个对象的一些功能和常用的方法与属性:
ADODB.Connection 对象
负责链接目标数据库(可以指定服务器、用户账号、密码、数据库名称、数据库文件地址等等信息与指定数据库连接),还可以直接在已连接数据库的对象上调用 Execute 方法执行 SQL 语句。
常用的方法有:Open、Execute、Close,常用的属性有:State
ADODB.Connection.Open 方法用来连接数据库
ADODB.Connection.Execute 方法用来在已连接的数据库执行 SQL 语句
ADODB.Connection.Close 方法可以关闭已连接的数据库
ADODB.Connection.State 属性可以读取当前的连接状态
当然,ADODB.Connection 还有其它很多方法、属性与事件,不过通常不常用,上面这些通常的程序够用了,如果想深入了解别的属性或方法,可以看看 VS6 的 MSDN 说明。
ADODB.Recordset 对象
负责利用以连接好的 ADODB.Connection 对查询出来的数据进行进一步的处理,所以 ADODB.Recordset 在使用是需要关联 ADODB.Connection 对象一起使用。
常用的方法有:Open、MoveNext、Move、Close,常用的属性有:RecordCount、Fields、EOF等。
当然像 AddNew、UpdateBatch、MoveFirst、MoveLast、MovePrevious、Delete 等等也是比较常用的,只是如果玩 SQL 语句进行创建、查询、插入、删除等操作,这些方法属性等都很少用到。
ADODB.Recordset.Open 指定 ADODB.Connection 对象查询指定的 SQL语句
ADODB.Recordset.MoveNext 将当前记录向下移动一条
ADODB.Recordset.Move 将当前记录向上或向下移动到指定的条数,可以输入负数或正数
ADODB.Recordset.Close 关闭查询结果
ADODB.Recordset.RecordCount 取得已查询的数据条数(要得到数据条数不建议使用该属性,可以用SQL语句的Count聚合函数统计出数据结果,效率会更高)
ADODB.Recordset.Fields 取得已查询的出的字段信息,包含字段名称、类型、数据等都可以读取或设置
ADODB.Recordset.EOF 可以在死循环里判断是否移动到了数据结尾以结束死循环
有了这两个对象后基本上就可以对数据库进行任何操作了,之后的关键就是去了解 SQL 语句了,不同的数据库在 SQL 语句的使用上会略有不同,但也是大同小异的,如 ACCESS的日期类型和MS SQLServer 的日期类型就有少许区别,ACCESS是用 #2019-12-06# 来指定日期,而 MS SQLServer 是用 '2019-12-06' 来指定日期等大同小异的区别。
现在我们可以来看看具体的使用案例了:
由于我们之前在工程里引用的 ADO 对象,所以我们可以在窗口代码里直接定义Connection与Recordset类型的变量,如:
- Private Sub Form_Load()
- Dim conn As Connection
- Dim rs As Recordset
-
- End Sub
但是,VB的对象使用是需要初始化的,所以我们还需要为这两个对象变量进行初始化,过程如下:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- End Sub
接着我们需要先链接数据库,然后才能对数据库进行创建、查询、修改、插入、删除等操作,所以我们先来了解一下如何链接数据库。链接数据库之前有介绍,我们可以通过 Connection 的 Open 方法来连接数据库,具体格式是:
对象.Open 字符串类型的连接语句,例如我们尝试链接一个存放在 d:\1.mdb 的 ACCESS 数据库,我们可以这样进行连接:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 连接 ACCESS 数据库
- conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
-
- End Sub
但是,即使使用了 Open 方法尝试链接数据库也未必就能链接成功,因为可能文件被意外移动,文件被意外修改或是磁盘出现坏道什么的导致文件丢失,作为一个专业的软件不可能让一个不能确定的链接跑之后的程序的,所以需要对链接状态进行判断,确认链接状态不是关闭后才继续跑之后的程序,否则将提示错误做重新链接或退出程序之类的处理,如:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 连接 ACCESS 数据库
- conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '...
-
- End Sub
在开发这种 Open、Close 程序的时候,需要养成一个良好的习惯,就是当你写了 Open 之后,接着就想着在哪先写好 Close 过程,如:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 连接 ACCESS 数据库
- conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '...
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
然后我们来进一步说一说 Connection 的 Execute 方法,通常 Execute 方法都是用作那种不需要返回,只需要执行一次SQL性操作的情况下使用,如:创建数据表、插入数据、修改数据、删除数据时使用,所以,接下来我们尝试在一个数据表中实现数据的插入、修改、删除等操作。例如我们 d:\1.mdb ACCESS数据库中有一个名为 user 的表,字段分别有 id、uid()、pwd、uname、sex,bd等,类型如图:
然后我们尝试插入一条数据,代码如下:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 连接 ACCESS 数据库
- conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '---------- 插入数据 ----------
- conn.Execute "INSERT INTO `user` (`uid`,`pwd`,`uname`,`sex`,`bd`) VALUES ('sk','123','人类',1,#2019-12-06#)"
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
然后我们先确保关掉 ACCESS 的情况下尝试运行程序,再用 ACCESS 打开数据库看看结果,发现数据已经插入成功了:
但这时候我们会发现如果要同时插入多条数据SQL语句会很长,这时候还是直接在 Execute 方法后放字符串会很难管理字符串,所以我们可以在程序开头多定义一个字符串变量出来专门存储SQL语句,这样使用起来代码格式看起来会整洁很多:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '---------- 插入数据 ----------
- SQL = "INSERT INTO `user` ("
- SQL = SQL & "`uid`,"
- SQL = SQL & "`pwd`,"
- SQL = SQL & "`uname`,"
- SQL = SQL & "`sex`,"
- SQL = SQL & "`bd`"
- SQL = SQL & ") VALUES "
- SQL = SQL & "('sk','123','人类',1,#2019-12-06#)"
-
- conn.Execute SQL
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
然后我们再尝试一下删除所有数据
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '---------- 删除数据 ----------
- SQL = "DELETE FROM `user`"
- conn.Execute SQL
-
- '---------- 插入数据 ----------
- SQL = "INSERT INTO `user` ("
- SQL = SQL & "`uid`,"
- SQL = SQL & "`pwd`,"
- SQL = SQL & "`uname`,"
- SQL = SQL & "`sex`,"
- SQL = SQL & "`bd`"
- SQL = SQL & ") VALUES "
- SQL = SQL & "('sk','123','人类',1,#2019-12-06#)"
- conn.Execute SQL
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
这个时候我们再运行一次程序,会发现原先 ID 为 1 的数据变成了 ID 为 2 的数据,这是因为原来添加的那条 ID 为 1 的数据在程序一运行时就被无差别的清理掉了,然后这条 ID 为 2 数据是刚刚运行的程序才插入进去的。
然后我们再尝试着同时加几条数据并尝试修改某条数据看看:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
- Dim SQL_INSERT As String ' 定义一个字符串变量用来存储 SQL INSERT 语句
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '---------- 删除数据 ----------
- SQL = "DELETE FROM `user`"
- conn.Execute SQL
-
- '---------- 插入数据 ----------
- SQL_INSERT = "INSERT INTO `user` (`uid`,`pwd`,`uname`,`sex`,`bd`) VALUES "
-
- SQL = SQL_INSERT & "('sk','123','人类',1,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('ii','111','测试1',0,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('jjj','222','测试2',0,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('kk','333','测试3',0,#2019-12-06#)"
- conn.Execute SQL
-
- '---------- 修改数据 ----------
- ' 指定条件为 UID 为 jjj 的数据,将其 uname 改为 TestUserName, sex 改为 1
- SQL = "UPDATE `user` SET `uname`='TestUserName',`sex`=1 WHERE `uid`='jjj';"
- conn.Execute SQL
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
然后可以发现数据库添加了有4条数据, UID 为 jjj 的数据 uname 变成了 TestUserName:
但老是这么用ACCESS来读数据也不是个办法,所以当我们了解了删除、插入、修改数据后,我们就来了解一下查询数据的方法了,让我们先按照步骤,先看看输入一个查询语句查询数据表的过程代码:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
- Dim SQL_INSERT As String ' 定义一个字符串变量用来存储 SQL INSERT 语句
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '---------- 删除数据 ----------
- SQL = "DELETE FROM `user`"
- conn.Execute SQL
-
- '---------- 插入数据 ----------
- SQL_INSERT = "INSERT INTO `user` (`uid`,`pwd`,`uname`,`sex`,`bd`) VALUES "
-
- SQL = SQL_INSERT & "('sk','123','人类',1,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('ii','111','测试1',0,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('jjj','222','测试2',0,#2019-12-06#)"
- conn.Execute SQL
-
- SQL = SQL_INSERT & "('kk','333','测试3',0,#2019-12-06#)"
- conn.Execute SQL
-
- '---------- 修改数据 ----------
- ' 指定条件为 UID 为 jjj 的数据,将其 uname 改为 TestUserName, sex 改为 1
- SQL = "UPDATE `user` SET `uname`='TestUserName',`sex`=1 WHERE `uid`='jjj';"
- conn.Execute SQL
-
- '---------- 查询数据 ----------
- SQL = "SELECT * FROM `user`"
- rs.Open SQL, conn, adOpenStatic, adLockReadOnly
-
- rs.Close
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
- End Sub
看到查询语句部分很简单,就是记录集 rs 指定数据连接对象 conn 用已设置好的 SQL 语句查询并返回结果,然后记录集 rs 把存入相关属性或对象中,如把字段相关的结果存入记录集内的 Fields 对象中,当前是否是最后一条记录存到 EOF 属性中等等。所以这时候我们可以使用 RecordCount 属性的读取取得查询到的数据条数,这样就可以用 For 语句循环指定的次数,然后在每一次循环过程中向下移动一下数据就可以读取所有的数据并输出出来,如:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
- Dim SQL_INSERT As String ' 定义一个字符串变量用来存储 SQL INSERT 语句
- Dim i As Long ' 定义一个整数变量用作循环语句使用
- Dim str_out As String ' 定义一个字符串变量用作输出文本用
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '...
-
- '---------- 查询数据 ----------
- str_out = ""
- SQL = "SELECT * FROM `user`"
- rs.Open SQL, conn, adOpenStatic, adLockReadOnly
- For i = 1 To rs.RecordCount
- If i > 1 Then
- str_out = str_out & vbCrLf
- End If
- str_out = str_out & rs!id & vbTab & rs!uname & vbTab & rs!uid & vbTab & rs!pwd
- If i < rs.RecordCount Then rs.MoveNext
- Next i
- rs.Close
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
-
- MsgBox str_out, 64, "数据"
- End
- End Sub
也可以用 Do loop 这类死循环通过读取 EOF 属性来读取全部数据,如:
- Private Sub Form_Load()
- Dim conn As Connection ' 定义数据连接对象变量
- Dim rs As Recordset ' 定义记录集对象变量
- Dim SQL As String ' 定义一个字符串变量用来存储 SQL 语句
- Dim SQL_INSERT As String ' 定义一个字符串变量用来存储 SQL INSERT 语句
- Dim i As Long ' 定义一个整数变量用作循环语句使用
- Dim str_out As String ' 定义一个字符串变量用作输出文本用
-
- Set conn = New Connection ' 初始化数据连接对象
- Set rs = New Recordset ' 初始化记录集对象变量
-
- ' 设置数据库连接语句
- SQL = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\1.mdb"
- ' 连接 ACCESS 数据库
- conn.Open SQL
- If conn.State = 0 Then
- MsgBox "连接数据库失败,请您确定"
- End
- End If
-
- ' 已经正常连接数据库
- '...
-
- '---------- 查询数据 ----------
- str_out = ""
- SQL = "SELECT * FROM `user`"
- rs.Open SQL, conn, adOpenStatic, adLockReadOnly
- i = 1
- Do While Not rs.EOF
- If i > 1 Then
- str_out = str_out & vbCrLf
- End If
- str_out = str_out & rs!id & vbTab & rs!uname & vbTab & rs!uid & vbTab & rs!pwd
- i = i + 1
- If Not rs.EOF Then rs.MoveNext
- Loop
- rs.Close
-
-
- ' 完成所有数据操作关闭数据连接
- conn.Close
-
- MsgBox str_out, 64, "数据"
- End
- End Sub
好了,这里就基本上算是能够插入、修改、删除、读取数据库了,如果想把查询的内容放到数据表内,可以用一些第三方表格控件来处理,通常都支持行列设置的,自己按行列设置表格数据,这样灵活性会很高,对于一些复杂的第三方表格控件来说,还支持合并表格,多表头的处理,用这种方法读写数据会快很多。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。