编写数据库应用程序必看.docx
《编写数据库应用程序必看.docx》由会员分享,可在线阅读,更多相关《编写数据库应用程序必看.docx(28页珍藏版)》请在冰豆网上搜索。
![编写数据库应用程序必看.docx](https://file1.bdocx.com/fileroot1/2023-1/8/ffc097f3-9279-429a-ba9d-415d10cc375e/ffc097f3-9279-429a-ba9d-415d10cc375e1.gif)
编写数据库应用程序必看
编写数据库应用程序必看----强烈推荐
第一节ODBCAPI
一、简介
现在最流行的联接数据源的方法,是ODBC(OpenDatabaseConnectivity
API),字面意思是“打开数据库联接”,这是一种用C/C++编的应用程序接
口,是属于Windows的一部分。
无论对任何一种客户/服务器关系型数据库接
口(RDBMS),还是目前最流行的索引顺序访问方法(ISAM)数据库(Jet,
Foxpro)以及电子表格,都能找到ODBC驱动程序。
使用ODBC数据源的一个最有利的优点是,只要利用ODBC联接上数据库,那
么,不论何种数据库,在应用程序内的处理方法都是相同的,这就为设计大型
通用数据库处理程序,提供了现实的保证。
ODBC是由Windows的动态链接库(DLL)组成的,内部提供了一系列的函
数,它由两组函数组成,提供基本的数据库服务:
1)添加、配置和删除ODBC数据源:
数据源是对数据库的有名联接,数据源的名字是由数据库的提供者命名的,
通常称为数据源名(DSN),注意把数据源的名字和数据库的名字区别开来。
ODBC使用Odbcinst.dll库来配置和删除数据源。
而它的可执行的程序,是
Odbc32.exe。
它的图标位于“控制面板”窗口中(ODBC数据管理器)。
2)管理从客户前端到数据库服务器的查询语句和其它SQL语句的通讯,
并返回查询结果。
数据源的ODBC驱动程序将客户端送来的SQL语句送到数据库驱动程序,数
据库驱动程序处理SQL语句后,再通过数据源的ODBC驱动程序将结果返回到应
用程序。
事实上,连接数据原有两种方式,一种是直接调用数据表名(Table),
这种方法是把所有的表内容全部传给客户端,当表很大时,将是一种效率很差
的传输方式。
第二种是使用SQL语句,它只把符合要求的内容传递下去,因此
应用效率比较高,大型数据库一般都采用SQL语句的方式。
下面简单介绍一下ODBC驱动程序。
ODBC驱动程序分为单层和多层两种:
单层的ODBC不能直接处理SQL语言,它是将SQL语句分解成一系列长的低
级指令,直接操作数据库文件(Dbase、Foxpro、Paradox、Excel)。
多层ODBC依靠客户/服务器RDBMS来处理SQL语句,由于服务器只传回符合
SQL条件的内容,网络流量被最小化。
VB6.0中包括SQLserver4.2X、6.X、
7.0的32位ODBC驱动程序,即Sqlsvr32.dll,虽然列表上同样也包括Qracle
驱动程序。
但是,实际使用时还是需要在客户端计算机上安装Qracle公司提供
的动态联接库。
二、ODBC添加新数据源
方法:
Windows-〉控制面板-〉资源管理器(Windows2000为管理工具)-〉
ODBC数据源(32位)。
打开“ODBC数据管理器”
这里首先要决定的是采用“用户DSN”还是“系统DSN”
用户DSN:
该数据源名只提供给用该用户名登陆的用户。
在网络使用时
主要用于在客户端定义数据源。
系统DSN:
该数据源名提供给用任何用户名登陆的用户,包括在网络上
(NT)使用。
添加:
选择驱动程序。
1)选择Access,-〉完成安装:
数据源名:
自己给出
数据库“选择”-〉选择相应的数
据库。
确定:
我们可以在数据源列表中看到新定义的数
据源名字。
2)选择SQLServer-〉完成建立新的数据源到SQLServer
命名数据源:
自己给出
服务器:
给出服务器名
如果从列表中选择服务器名称,则不需要更
多的配置。
如果使用相同的计算机作为SQLServer,
可以在此服务器框中输入“(local)”(本地)。
然后用户可连接到SQLServer的本地副本,即
便正在运行SQLServer的非网络版本。
在说明框可以写进关于数据源可选的描述性
说明。
例如,“所有员工的工资和销售情况”。
下一步
使用用户登陆ID和密码的SQLServer验证
输入用户名和密码
下一步-〉完成配置
可以看出,不同的驱动程序配置方法不尽相同。
后面就可以看到,使用ODBC数据源名并不是唯一的选择,我们也可以使
用直接用数据库名或者服务器名(SQLServer)联接的方式,这时,并不需
要事先设置ODBC数据源的名字。
第二节DAO和ADO的技术状态
1994年,微软在Access2.0中首先引入了16位的DAO(DataAccessing
Object数据访问对象),以实现和Jet数据库引擎的连接,这是允许程序
员操纵Jet引擎的第一个面向对象的接口。
DAO提供了一个复杂的可编程数据对象的层次模型,由上到下分别是:
DBEngine
Workspace
Database
TableDef
QueryDef
Recorset
DAO的使用非常复杂,例如,为了引用Recorset,必须从上到下逐级
引用:
DIMwnameAsDAO.Workspace
DIMwm1AsDAO.Database
DIMwm2AsDAO.TableDef
DIMwm3AsDAO.QueryDef
DIMwm4AsDAO.Recorset
setwname=DBEngine.Workspace(0)
.....
更重要的,DAO/Jet并不适合客户/服务器模式的数据库系统,于是,
微软又开发出了RDO(RemoteDataObject远程数据对象),和RDC控
件(在MSRemoteDataControl6.0下),解决了客户/服务器模式下,开
发象SQLServer或Oracle这些大型远程数据库的困难。
VB提供的RDO组件在工程-〉引用:
客户端:
MSRemoteDataObject2.0
服务器端:
MSRemoteDataServers2.5Library
和
MSRemoteDataServersServer2.5Library
显然,这种模式需要编写服务器端程序,在某些情况下可能是不现
实的。
继RDO之后,微软又提出了全新的ADO技术(ActiveXDataObject
),ADO是DAO和RDO的继承者,它基于微软提出来的OLEDB数据访问
模式,它可以处理目前几乎全部关系型数据库和非关系型数据库系统。
而且,它是专门为大范围的商业数据库系统设计的,ADO比DAO占用
内存少,所以它更适合大流量和大事务量的网络计算机系统。
ADO的影响很大,现在几乎所有的非微软开发环境都内置了ADO驱
动程序。
ADO的使用也相当方便,利用ADODC控件(在MSADOData
Control6.0(OLEDB)下),可以在本地计算机上获取本地和远程的数据
源,并且可以立刻测试联接是否成功。
ADODC控件,是以ADO为父类的一个子类,所以,它继承了ADO的
几乎绝大多数属性事件和方法,同时,也加入了自己的属性事件和方法。
这些属性事件和方法,又大多数套用于一种原来基于DAO的控件Data,
为熟悉Data控件的程序员做一个合理的过渡,并且,加入了和数据绑定
控件连接的内容。
所以,同一种目的,在ADODC中可以有两种方式解决,这样做的好
处是给程序员带来了方便,更重要的,ADODC和数据绑定控件连接非常
方便,但代价是无疑降低了效率。
因此,尽管使用ADODC控件处理数据库问题相当方便,但是,在更
多的大型数据库系统的设计中,人们还是使用直接调用ADO类的方式,
因为这样一来,程序的效率往往更高,更灵活。
鉴于这个情况,在下面的讨论中,我们两种情况都进行讨论,具体
怎么用,要看项目的需要。
当然首先是从源头说起,先研究ADO。
还需要说明的是:
ADODC提供了一整套的自动联接方式,这些方式,
十分方便,但是,如果不明白原理,往往联接以后还是感到自己心中无
数,所以,即使您使用ADODC,但是仔细的研究ADO本身的东西,也还
是很有必要的。
同时,利用ADODC提供的信息,也给以编程为主的ADO
提供了方便,这些我们后面都会加以介绍。
最近一两年,ADO技术又有了长足的发展,这里首先要提到微软的
VisualStudio.Net平台,在这个平台上的主导语言是VisualBasic,
VisualC++,VisualC#,对于VB6.0的编程人员,过渡到VB.NET是理
所当然的事情。
微软公司对VB升级到VB.Net的同时,对数据访问模型进行了翻天覆
地的升级。
把原来的ADO模型升级为全新的ADO.NET数据源,
原来最重要的RecordSet现在消失了,取而代之的是DataSet和
DataReader,而且不再像原来RecordSet那样一次只读取一条记录,而
是读取整个数据库,然后在内存中建立一个映像,从而实现了断开方式
数据库连接和内存管理自动化,这是微软的一个重大的技术突破。
但是,这并不等于说学习ADO技术就没有意义了,首先,由于技术
的继承性,ADO.NET继承了ADO的大部分编程方法,另一方面,VB.NET
也还是保留了原来在VB6.0中ADO的COM组件,这就是说,在VB.Net中,
我们还是可以用在VB6.0中完全相同的方法来编写数据库程序,这对于
中小规模的数据库管理系统,也是很有意义的。
如果您主要是处理Access数据库,那么使用专为Access数据库编写
的DAO技术将更直接效率更高。
因此,在VB.Net中也仍然保留了DAO的
COM组件,但是,更改了驱动程序,解决了在VB6.0中DAO不能驱动
Access2000的问题,因此也得到了广泛的应用。
下面,我们就来仔细的研究ADO和DAO的有关问题。
在课程的最后,
我们将通过一两个例子,来说明VB.NET中数据库处理的一些方法和特点。
第三节ADO最基本的内容
ADO的内容比较多,我想还是分两个层,先讨论最基本最重要的内
容。
一、ADO组件的引用
ADO实际上是个COM组件,它的顶层有三个对象:
Connection:
指定数据源,建立和数据源的连接;
Command:
对数据源执行指定的命令,接受SQL语句,表名,存储
过程的名字,执行SQL查询,更新数据,插入记录等;
Recordset:
来自表或命令执行结果的记录全集,操纵来自提供者
的几乎所有数据。
要应用ADO组件,必须在工程-〉引用:
MsActivexdataobject2.7Library
把ADO这个COM组件调入当前系统。
用F2可以看到这个组件的状况。
库的名字为ADODB,也就是在当初
设计组件的时候,工程名起的是是ADODB,所以,应用这三个类都要构造
相应的实例,引用时必须作如下声明,:
DimCnnAsADODB.Connection
DimCmmAsADODB.Command
DimRecoAsADODB.Recordset
其中,Cnn,Cmm和Reco是用户自定义的对象变量,为了表述方便,
后面的讨论我们都以这组名字作为表达的基础。
真正使用,就要通过New来建立一个ADO的实例。
SetCnn=NewADODB.Connection
SetCmm=NewADODB.Command
SetReco=NewADODB.Recordset
有时,希望定义的同时构造实例,也可以写成(ADODB一般可以不写):
DimCnnAsNewConnection
DimCmmAsNewCommand
DimRecoAsNewRecordset
值得指出的是,如果您直接使用ADODC控件,那上述方法都已经在
ADODC内部完成了,不需要程序员自己来写。
但是,如果您不使用ADODC
控件,而要使用ADO这个类来编写数据库系统的时候,就需要使用引
用COM的标准方法。
一、数据库连接的建立
可以有四种连接方式:
第一种(用Open)
Cnn.Provider="驱动程序"
Cnn.Open"数据库名"[,"用户名","密码"]
例
Cnn.Provider="Microsoft.Jet.OLEDB.4.0"
Cnn.OpenAdd.path&"\奖金数据库.mdb"
这里App.path给出了当前路径(该语句在VB.NET中变为
Application.startuppath),这样就可以实现相对路径调用数
据库了。
第二种(用连接字符串)
Connection对象变量有一个Connectionstring,可以输入字符串,
例如对于sqlserver数据库,字符串设置可用如下规则:
Provider=SQLOLEDB.1;(提供者)
IntegratedSecurity=SSPI;(安全设置)
PersistSecurityInfo=False;(持续的安全信息)
InitialCatalog=pubs;(初始的目录,或默认的数据库)
DataSource=XXX-PE(数据源--计算机名)
请看如下的例子:
Cnn.DefaultDatabase="pubs"
'这个属性是指定默认数据库,如果没有指定数据库名,
'就使用这里指定的数据库名,SQLServer通常是pubs
Cnn.Connectionstring="driver={SQLServer};Server=bigs;_
uld=sa;pws=pwd"
'其中:
bigs为服务器名;sa为用户名;pwd为密码。
Cnn.Mode=adModeShareExclusive
'以独占方式打开(后面会讨论)
Cnn.open
第三种(使用DSN数据源名)
Cnn.Connectionstring="DSN=pubs;UID=***;PWD=***"
'由于建立DSN时就已经提供了诸如上面有关的各种数据,
'所以这里只需要直接调用名字就可以了。
Cnn.open
第四种(直接用Open打开)
Cnn.Open"DSN数据源名","用户名","密码"
实例,第一部分,建立三个数据库的连接:
-----------------------------------------------------------------
建立三个Button,分别用三种方法打开三个库,运行时不出错就代表
已连接。
由于后面要用一个显示画面,所以一次只能打开一个数据库,看
看这里是怎么解决这个问题的?
-----------------------------------------------------------------
DimCnnAsNewConnection
DimCmmAsNewCommand
DimRecoAsNewRecordset
DimCnn1AsNewConnection
DimCnn2AsNewConnection
DimKzr,Kzc,kzc1,kzc2,Nd,inname,Tname
PrivateSubCommand2_Click()
'用字符串连接SQLSERVER数据库
IfKzc=TrueThenCnn.Close
Kzc=True
Ifkzc1=TrueThen
Cnn1.Close
kzc1=False
EndIf
Ifkzc2=TrueThen
Cnn2.Close
kzc2=False
EndIf
Cnn.ConnectionString="Provider=SQLOLEDB.1;IntegratedSecurity=SSPI;PersistSecurityInfo=False;InitialCatalog=pubs;DataSource=XXX-PE"
'注意一下计算机名要更改
Cnn.Open
EndSub
PrivateSubCommand1_Click()
'打开数据库的Provider+Open方法
Ifkzc1=TrueThenCnn1.Close
kzc1=True
IfKzc=TrueThen
Cnn.Close
Kzc=False
EndIf
Ifkzc2=TrueThen
Cnn2.Close
kzc2=False
EndIf
Cnn1.Provider="Microsoft.Jet.OLEDB.4.0"
inname=App.Path&"\奖金数据库.mdb"
Cnn1.Openinname
Tname="奖金"
EndSub
PrivateSubCommand3_Click()
'直接使用OPEN和DSN数据源打开数据库
Ifkzc2=TrueThenCnn2.Close
kzc2=True
IfKzc=TrueThen
Cnn.Close
Kzc=False
EndIf
Ifkzc1=TrueThen
Cnn1.Close
kzc1=False
EndIf
Cnn2.Open"Mysql"
EndSub
PrivateSubForm_Load()
Kzr=False
Kzc=False
kzc1=False
kzc2=False
EndSub
-----------------------------------------------------------------
二、应用Recordset打开表
前面已经提到,Recordset对象是用于处理来自表或命令执行结果的记
录全集,操纵来自提供者的几乎所有数据,所以,处理数据库问题,Recordset
是处在重中之重的位置,由于这是个COM对象,应用的时候同样需要声明,
并且构造一个实例:
DimRecoAsADODB.Recordset
SetReco=NewADODB.Recordset
Reco.Open"数据源",Cnn[,指针形态][,锁定方式]
其中:
数据源:
表名,或者SQL语句
指针形态:
0向后指针(默认)
1索引键集
3动态记录(常用)
4静态记录
锁定方式:
1只读(默认)
2编辑更新
3Updata更新
4批次更新
实例:
关于Recordset的打开
-------------------------------------------------------------
在相应的按钮事件中加上Reco.Open
-------------------------------------------------------------
PrivateSubCommand2_Click()
.............
Tname="employee"
Reco.OpenTname,Cnn,3,3
'双向指针,Updata更新
Kzr=True
EndSub
PrivateSubCommand1_Click()
...............................
Tname="奖金"
Reco.OpenTname,Cnn1,3,3
Kzr=True
EndSub
PrivateSubCommand3_Click()
....................
Tname="基本表"
Reco.OpenTname,Cnn2,3,3
Kzr=True
EndSub
-------------------------------------------------------------
三、几个重要的Connection对象方法
1)open方法
语法:
Cnn.Open[Connectionstring][,UserID][,password]
注意:
Connection的Open方法是连接了数据库,但并没有打开表。
2)Close方法
Cnn.Close
关闭已经打开的连接,但该对象还保留在内存中
3)清除内存
SetCnn=Noting
真正的消除掉
四、取得记录集中的数据
Reco.("字段名")
Reco.Fields(index).Value'内容
Reco.Fields(index).Name‘字段名
Reco.Fields(index).type'字段类型
Reco.Fields(i).ActualSize'字段长度
Reco.Fields.Count'字段总数
记录数
Reco.RecordCount记录数
N=Reco.AbsolutePosition'当前指针的位置
Reco.AbsolutePosition=N'把指针定位在第N笔记录上
五、指针的移动
Reco.MoveFirst'指针指向第一笔记录
Reco.MoveNext'指针指向下一笔记录
Reco.MovePrevious'指针指向上一笔记录
Reco.MoveLast'指针指向最后一笔记录
------------------------------------------------------------------
做一个frame用于显示,内部放置9个Textbox和Label数组。
开始的时候frame1.visible=false。
VarType()检测数据库输出是否为空(MULL),因为空数据的送
出会显示错误信息,应避免这种情况。
Showfiel()用于显示数据
Myscreen()用于设置初始屏幕
------------------------------------------------------------------
PrivateSubShowfiel()
Fori=0ToNd-1
IfVarType(Reco.Fields(i).Value)>1Then
Text1(i).Text=Reco.Fields(i).Value
Else
Text1(i).Text=""
EndIf
Next
EndSub
PrivateSubMyscreen()
Nd=Reco.Fields.Count
IfNd>=9Then
Nd=9
EndIf
Fori=0To8
Label1(i).Visible=False
Text1(i).Visible=False
Next
Fori=0ToNd-