Google

星期二, 五月 13, 2008

How To Control Your Updates in ADO Through "Update Criteria"

SUMMARY

The ADO Client Cursor Engine allows you to control how it builds the action queries that update the database according to the changes you make to the recordset object. This article is designed to help you understand how to control how ADO performs these updates.

Back to the top

MORE INFORMATION

When you open a recordset against the Customers table in the Northwind database (NWind.MDB) and use a client side cursor, ADO retrieves enough information about the structure of the table in order to use an action query to update the table.

An action query is a query that modifies a database and does not return data. For example, "UPDATE Customers SET CompanyName = 'Acme' WHERE CustomerID = 17" is an action query.

ADO determines which field, or set of fields, is the primary key and uses that information to make sure it can find the correct row in the database to update. If you are going to perform updates with the client cursor engine, make sure you have a primary key defined in your table. If you don't, you may accidentally update more rows than you intended.

When you use a client side recordset, ADO exposes a property in the recordset's Properties collection called "Update Criteria." This property allows you to control the information in the WHERE clause in the action query that ADO builds to update the database. The default value for this property is 2 - adCriteriaUpdCols. By default, ADO will use the primary key and all fields being updated in the WHERE clause of the action query. For example:
   rsCustomers.CursorLocation = adUseClient
rsCustomers.Open "SELECT * FROM Customers", cnNWind, _
adOpenStatic, adLockOptimistic, adCmdText
rsCustomers.Fields("CompanyName").Value = "Acme"
rsCustomers.Update
will cause ADO to execute the following action query
   UPDATE Customers SET CompanyName = 'Acme'
WHERE CustomerID = 'ALFKI' AND CompanyName = 'Alfreds Futterkiste'
The WHERE clause contains information about the primary key and the original value for the field to update. This ensures that if another user has modified the value of the CompanyName field to a value other than the value that ADO originally retrieved, ADO will not update that row and will raise an error instead.

To change the value of this property, use code similar to the following
   rsCustomers.CursorLocation = adUseClient
rsCustomers.Properties("Update Criteria").Value = adCriteriaAllCols
rsCustomers.Open "SELECT * FROM Customers", cnNWind, _
adOpenStatic, adLockOptimistic, adCmdText
rsCustomers.Fields("CompanyName").Value = "Acme"
rsCustomers.Update
This code will cause ADO to include every field in the WHERE clause. You would use this value for the "Update Criteria" property if you want to make sure that the update made by the current user will only succeed if no changes have been made to any fields in that row in the table.

The available constants for this property are as follows:
   adCriteriaKey = 0

Uses only the primary key

adCriteriaAllCols = 1

Uses all columns in the recordset

adCriteriaUpdCols = 2 (Default)

Uses only the columns in the recordset that have been modified

adCriteriaTimeStamp = 3

Uses the timestamp column (if available) in the recordset
NOTE: Specifying adCriteriaTimeStamp may actually use adCriteriaAllCols method to execute the Update if there is not a valid TimeStamp field in the table. Also, the timestamp field does not need to be in the recordset itself.

http://support.microsoft.com/default.aspx?scid=kb;EN-GB;q190727&GSSNB=1

标签: , ,

星期日, 五月 04, 2008

sql server 远程访问

在数据库的各种应用程序开发中,连接数据库是数据库应用程序开发的第一步,同时也是最重要的一步。而对于不同的数据库他们的连接模式各有不同,对应的连接串也不同。
程序员可能都有这样的经历,有时不知道连接数据库所需要的连接串究竟如何写或者经常写错而导致不能正确访问数据库。当然很多编程工具能够通过可视化的界面直接产生正确的连接字符串,但字符串中各个参数的具体含义也不清楚,经常混淆。本文就针对大部分常用数据库列举出不同连接方法所需要的连接字符串并加以说明,以便程序员参考!




Sql Server
· ODBC
o 标准连接(Standard Security):
"Driver={SQL Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;"
1)当服务器为本地时Server可以使用(local);
"Driver={SQL Server};Server=(local);Database=pubs;Uid=sa;Pwd=asdasd;"
2)当连接远程服务器时,需指定地址、端口号和网络库
"Driver={SQL Server};Server=130.120.110.001;Address=130.120.110.001,1052;Network=dbmssocn;
Database=pubs;Uid=sa;Pwd=asdasd;"
注:Address参数必须为IP地址,而且必须包括端口号
o 信任连接(Trusted connection): (Microsoft Windows NT 集成了安全性)
"Driver={SQL Server};Server=Aron1;Database=pubs;Trusted_Connection=yes;"
或者
"Driver={SQL Server};Server=Aron1;Database=pubs; Uid=;Pwd=;"
o 连接时弹出输入用户名和口令对话框:
Conn.Properties("Prompt") = adPromptAlways
Conn.Open "Driver={SQL Server};Server=Aron1;DataBase=pubs;"
· OLE DB, OleDbConnection (.NET)
o 标准连接(Standard Security):
"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;"
o 信任连接(Trusted connection):
"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;"
(如果连接一个具体的已命名SQLServer实例,使用Data Source=Servere NameInstance Name;但仅适用于 SQLServer2000)例如:”Provider=sqloledb;Data Source=MyServerNameMyInstanceName;Initial Catalog=MyDatabaseName;User Id=MyUsername;Password=MyPassword;”
o 连接时弹出输入用户名和口令对话框:
Conn.Provider = "sqloledb"
Conn.Properties("Prompt") = adPromptAlways
Conn.Open "Data Source=Aron1;Initial Catalog=pubs;"
o 通过IP地址连接:
"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
(DBMSSOCN=TCP/IP代替Named Pipes, Data Source的末尾是需要使用的端口号(缺省为1433))
· SqlConnection (.NET)
o 标准连接(Standard Security):
"Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;"
或者
"Server=Aron1;Database=pubs;User ID=sa;Password=asdasd;Trusted_Connection=False"
(这两个连接串的结果相同)
o 信任连接(Trusted connection):
"Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;"
或者
"Server=Aron1;Database=pubs;Trusted_Connection=True;"
(这两个连接串的结果相同)
(可以用serverNameinstanceName代替Data Source,取值为一个具体的SQLServer实例,但仅适用于 SQLServer2000)
o 通过IP地址连接:
"Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
(DBMSSOCN=TCP/IP代替Named Pipes, Data Source的末尾是需要使用的端口号(缺省为1433))
o SqlConnection连接的声明:
C#:
using System.Data.SqlClient;
SqlConnection SQLConn = new SqlConnection();
SQLConn.ConnectionString="my connectionstring";
SQLConn.Open();

VB.NET:
Imports System.Data.SqlClient
Dim SQLConn As SqlConnection = New SqlConnection()
SQLConn.ConnectionString="my connectionstring"
SQLConn.Open()
· Data Shape
o MS Data Shape
"Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=Aron1;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
· 更多
o 如何定义使用哪个协议
§ 举例:
"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;"
名称 网络协议库
dbnmpntw Win32 Named Pipes
dbmssocn Win32 Winsock TCP/IP
dbmsspxn Win32 SPX/IPX
dbmsvinn Win32 Banyan Vines
dbmsrpcn Win32 Multi-Protocol (Windows RPC)
§ 重要提示
当通过SQLOLEDB提供者进行连接时使用以下语法:
Network Library=dbmssocn
但通过MSDASQL提供者进行连接时使用以下语法:
Network=dbmssocn
o 所有SqlConnection连接串属性
§ 下表显示了ADO.NET SqlConnection对象的所有连接串属性. 其中大多数的属性也在ADO中使用.所有属性和描述来自于msdn.
名称 缺省值 描述
Application Name 应用程序名称或者当没有提供应用程序时为.Net SqlClient数据提供者
AttachDBFilename或者extended properties或者Initial File Name 主要文件的名字,包括相关联数据库的全路径。数据库名字必须通过关键字'database'来指定。
Connect Timeout或者Connection Timeout 15 在中止连接请求,产生错误之前等待服务器连接的时间(以秒为单位)
Connection Lifetime 0 当一个连接返回到连接池,当前时间与连接创建时间的差值,如果时间段超过了指定的连接生存时间,此连接就被破坏。它用于聚集设置中在运行服务器和准备上线 的服务器之间强制负载平衡。
Connection Reset 'true' 当连接从连接池移走时决定是否重置数据库连接。当设置为'false'时用于避免获得连接时的额外服务器往复代价。
Current Language SQL Server语言记录名称
Data Source或Server或Address或Addr或Network Address 要连接的SQL Server实例的名字或者网络地址
Enlist 'true' 为真时,连接池自动列出创建线程的当前事务上下文中的连接。
Initial Catalog或Database 数据库名
Integrated Security或者Trusted_Connection 'false' 连接是否为信任连接。其取值为'true', 'false'和'sspi'(等于'true').
Max Pool Size 100 连接池中允许的最大连接数
Min Pool Size 0 连接池中允许的最小连接数
Network Library或Net 'dbmssocn' 网络库用于建立与一个 SQL Server实例的连接。值包括dbnmpntw (命名管道), dbmsrpcn (多协议), dbmsadsn (Apple Talk), dbmsgnet (VIA), dbmsipcn (共享内存) 和 dbmsspxn (IPX/SPX), 和 dbmssocn (TCP/IP). 所连接的系统必须安装相应的动态链接库。如果你没有指定网络,当你使用一个局部的服务器 (例如, "." 或者 "(local)"),将使用共享内存
Packet Size 8192 与 SQL Server的一个实例通讯的网络包字节大小
Password-或Pwd SQL Server帐户登录口令
Persist Security Info 'false' 设置为'false',当连接已经打开或者一直处于打开状态时,敏感性的安全信息 (如口令)不会返回作为连接的一部分信息。
Pooling 'true' 为真时,从合适的连接池中取出SQLConnection对象,或者必要时创建SQLConnection对象并把它增加到合适的连接池中。
User ID SQL Server登录用户
Workstation ID the local computer name 连接到SQL Server的工作站名称
§ 注意:
使用分号分隔每个属性
如果一个名字出现多于两次,在连接串中的最后一次出现的值将被使用。
如果你通过在应用中由用户输入字段的值来构建连接串,你必须保证用户不会通过用户值里的另一个值插入到一个额外的属

性来改变连接串。

http://topic.csdn.net/t/20041223/10/3669416.html

标签: , ,

星期三, 四月 09, 2008

ADOConnect时如何根据返回信息判断

try
...
Except
if TADOconnection.Errors.Count>0 then
Case TADOconnection.Errors[0].NativeError of
xx:...
End;
End;
TADOconnection.Errors[0].NativeError中返回的是数据库原始错误编号,根据此编号查数据库帮助就可以得知具体的错误信息。比如Oracle的1005,1017号就是用户名或密码错,12154是服务器不存在。

TADOconnection.Errors[0].Description
TADOconnection.Errors[0].Number

http://topic.csdn.net/t/20011006/23/313923.html

标签: ,

星期四, 三月 20, 2008

use wxwidgets and ado in vc.net

use wxwidgets and ado in vc.net 用mfc总是让人觉得别扭,
  比较一下第三方的图形库,wxwidgets不错
  要操作数据库,当然是用ado库
  我编译好wxwidgets后,在example里找到grid的example开刀
  把那些杂七杂八的东西删了
  #include
  #import "c:\Program Files\Common Files\System\ADO\msado15.dll" rename("EOF", "EndOfFile")
  using namespace ADODB;
  再GridFrame::GridFrame()中添加
  CoInitialize(0);
  HRESULT hr;
  _ConnectionPtr myConnection;
  myConnection.CreateInstance(__uuidofConnection));
  hr=myConnection->Open("Provider=SQLOLEDB.1;SERVER=ZZU- CZX;DATABASE=friend","sa","letmein",0);
  _CommandPtr pCommand;
  pCommand.CreateInstance(__uuidof(Command));
  pCommand->ActiveConnection=myConnection; pCommand->CommandText="select * from t1";
  _RecordsetPtr pRecordset;
  pRecordset.CreateInstance(__uuidof(Recordset));
  pRecordset->CursorLocation=adUseClient;
  pRecordset->Open((IDispatch*)pCommand,vtMissing,adOpenStatic,adLockBatchOptimistic,adCmdUnknown);
  找了个合适的地方添加
  _variant_t data;
  grid = new wxGrid( this,wxID_ANY,wxPoint( 0, 0 ));
  grid->CreateGrid( pRecordset->GetRecordCount(), 3 );
  for (int row = 0; row <>GetRows(); row++)
  {
  data=pRecordset->GetCollect("name");
  grid->SetCellValue(row,0,(wxString)_bstr_t(data));
  pRecordset->MoveNext();
  }
  大概就是这样,总之我觉得理解了就很简单,而且用起来也方便

http://www.wangchao.net.cn/bbsdetail_65840.html

标签: , ,

星期三, 二月 13, 2008

delphi实现ado的高级功能

ADO是Microsoft存取通用数据源的标准引擎。ADO通过封装OLE DB而能够存取不同类型的数据,让应用程序能很方便地通过统一的接口处理各种数据库。ADO由一组COM对象组成,每一个不同的原生ADO对象负责不同的工作。下面,向大家介绍如何使用原生ADO对象的动态属性来实现ADO的高级功能。www.sq120.com推荐文章

  ADO原生对象关系图:
  Connection
  Errors→Error
  Command→Parameters→Parameter
  RecordSet→Fields→Field
一、存取原生ADO对象
   Delphi中的ADO组件页中的组件为我们通过ADO技术访问数据库提供了方便。这些组件封装了原生的ADO对象。虽然我们利用ADO组件页中的组件 也能编写出有效率的数据库程序,但是ADO中的一些属性和方法仍然是ADOExpress组件没有封装进去的,而此时,需要使用这些没有封装的属性和方 法,必须还得通过存取原生的ADO对象来使用这些属性和方法。
  在ADO组件中,每个组件都有一个属性让程序员通过它来存取它所封装的原生ADO对象。下面我们用表1来说明ADO组件页中ADO组件封装原生ADO对象的属性:
  在程序中访问ADO组件封装的原生ADO对象,例如:
  Var
  MyRS :_RecordSet;
  MyRS :=ADODataSet1.RecordSet;
  以上这句就是访问组件封装的原生ADO对象RecordSet。


 
二、存取原生ADO对象的动态属性
  当我们用ADO组件编写针对特定数据库的应用程序时,ADO驱动程序会将特定数据库所能提供的功能存储在动态属性之中。在ADO模型中,每一个原生AD
  O对象都有一组动态属性。
  注意:在Delphi中,只能通过原生的ADO对象来存取动态属性。
  原生的ADO对象的动态属性集合存储在名为Properties的数组结构中,Properties数组中的每一个数组元素Property就对应一个特定的动态属性。因此,访问原生ADO对象的动态属性的基本步骤是:
  1. 通过ADO组件的属性访问其封装的原生的ADO对象;
  2. 利用原生的ADO对象访问其Properties动态属性集合;
  3. 在Properties动态属性集合中访问Property动态属性;
  4. 存取Property动态属性的值,实现ADO组件未封装的功能。
  Delphi为我们访问动态属性集合Properties提供了几个方便的接口函数供我们调用:
  Function Get_Item(Index : OleV
  ariant) :Property; SafeCall;//根据动态属性的索引值或名称获取动态属性
  Property Item[Index :OleVariant
  ] :Property Read Get_Item;//根据动态属性在集合中的索引值来获取动态属性
  Delphi也提供了以下的属性来方便地访问动态属性Propery的名称和值:
  Name 动态属性的名称
  Value 动态属性的值
  为了说明这些原理,我们用一个简单的例子来说明。这个例子中,程序运行后点击按钮,在Memo中就会显示原生的ADO对象RecordSet的所有动态属性。
  1. 建立一个新的工程,保存为Project1.dpr;
  2. 在主窗体上放置如下组件:
  TAdoConnection、TAdDataSet、TMemo、TButton
  3. 将TAdoConnection的Conne
  ctionString属性连接到SQL SERVE
  R 数据库的Pubs数据库;
  4. 设置TAdoDataSet的Connecti
  on属性为上一步中的TAdoConnecti
  on组件;
  5. 编写按钮的Button1Click事件处理函数代码如下:
  procedure TForm1.Button1Click(S
  ender: TObject);
  Var
  i :Integer;
  MyPty :Property_;
  MyPties :Properties;
  MyRS :_RecordSet;
  begin
  AdoDataSet1.Open;
  MyRS :=AdoDataSet1.RecordSet; //获取原生的ADO对象赋值给MyRS
  MyPties :=MyRS.Properties; //获取原生ADO对象的动态属性集合Prop
  erties赋值给MyPties
  For i :=0 to MyPties.Count-1 do //循环取得动态属性集合Properties中的每一个动态属性
  begin
  MyPty :=MyPties.Item[i]; //动态属性集合MyPites的Item属性根据索引值取得每一个动态属性赋值给MyPty
  Memo1.Lines.Add(MyPty.Name); //动态属性MyPty的Name属性表示该动态属性的名字,将动态属性的名字加入到Memo1列表中。
  end;
  end;

三、利用原生ADO对象实现ADO高级功能
  我们利用 ADO编写的数据库应用程序,总会涉及到数据更新的情况。当利用ADO将数据更新回数据库时,ADO必须依据一定的条件从数据库中找到将要被更新的原始记 录,然后用更新的字段值更新回数据库。ADO默认的更新条件是这样的,依据关键字段的值与被修改的字段的原始值在数据表中查找这样的记录,如果找到这条记 录,则用更新的字段值更新回数据库。这个所依据的更新条件也是原生ADO对象的动态属性来控制的,我们可以在程序运行中存取这个动态属性,达到修改更新条 件的目的。控制更新条件的动态属性是通过原生的ADO对象的RecordSet对象的UpdateCriteria动态属性来实现的。 UpdateCriteria动态属性取值的意义,见表2。


 
  其中adCriteriaUpCols是ADO的默认设置。在一个多人使用的系统中,很可能同一笔数据在相同时间被不同的用户修改,这时较好的设置UpdateCriteria的值,能极大程度地控制是否能成功地将数据更新回数据。例如:一个表有A、B、C三个字段,A是关键字段。用户甲更新了一条记录的B字段值,而此时用户乙更新了同一条记录的B字段的值,假设此时UpdateCriteria动态属性的值为adCriteria
  Key,用户乙的修改结果就会把用户甲的修改所覆盖。如果UpdateCriteria动态属性的值为adCriteriaUpCols,此时,用户乙的修改就不会成功,因为对字段B的值在数据库找不到原始记录。
  为了说明这个原理,我们用一个简单的例子来说明。这个例子中,我们修改原生ADO对象RecordSet的Update
  Criteria动态属性的值(默认为adCriteriaUpCols)为adCriteri
  aKey,即把ADO的更新条件设置为依据关键字段的值在数据表中寻找原始记录(如图)。


 
  1. 新建一个工程,命名为Project1.dpr。
  2. 在主窗体中放置如下组件:
  TAdoConnection:连接到SQL SERVER数据库服务器。
  TAdoTable:设置其Connection属性为上一步中的TAd
  oConnection组件,并设置TableName为数据库中一个表名。
  TDataSource:设置其DataSet属性为上一步的TAd
  oTable组件。
  TDBNavigator 、TDBGr
  id:设置其DataSource属性为上一步的TDataSource组件。
  3. 在主窗体的OnCreate事件处理函数中编写代码,来修改原生ADO对象的Upd
  ateCriteria动态属性值为adCr
  iteriaKey,访问原生ADO对象的动态属性的步骤见前面所述。代码如下:
  procedure TForm1.FormCreate(Sender: TObject);
  Var
  MyPty :Property_;
  MyPties :Properties;
  MyRS :_RecordSet;
  begin
  AdoTable1.Open; //打开数据集
  MyRS :=AdoTable1.RecordSet; //获取TAdoTable组件封装的原生的ADO对象RecordSet
  MyPties :=MyRS.Properties; //通过原生ADO对象获取Properties动态属性集合
  MyPty :=MyPties.Get_Item('Update Criteria'); //通过动态属性集合的Get_Item函数获取其中的动态属性Upda
  teCriteria的Value值。
  MyPty.Value :=adCriteriaKey;
  //注意:在程序中引用adCriteriaKey常量,必须在Uses子句中包括ADOInt单元。
  //如果不想另外引用ADOInt单元,可以直接用adCriteriaKe
  y代表的值0作为属性值赋值。
  //AdoTable1.Recordset.Properties.Get_Item('Update Criteria'
  ).Value :=adCriteriaKey; 这一句的功能和上面各句是一样的。
  End;
  ADO比BDE功能有了很大的提高。ADO对多表连接的查询结果就具有修改的能力,而BDE不能对多表连接的查询结果进行修改更新的操作,而必须依靠TUpdateSql组件来实现这个功能。ADO能自动地判断被修改的字段所属的表,然后分别更新回不同的表中。但是在对表连 接的查询结果作出删除操作时,ADO总会把两个表中的数据都删除掉。例如有一个员工表,一个定单表,将这两个表通过员工编号连接起来,作出删除操作时,同 时会将员工表中的数据,与定单表中的数据删除掉,这也许是我们不希望看到的,假设我们只希望删除掉一个员工接到的其中一笔定单记录,而不愿意把这个员工的 记录也删除掉,这个时候我们应该怎么办呢? 在ADO中的原生ADO对象的Unique Table动态属性负责控制这个功能,设置Unique Table的值为多表连接中某一个数据表的名称,就能实现在多表连接中删除指定表的记录。
  在这个例子中,我们通过原生ADO对象的动态属性Unique Table,实现在多表连接的结果集中,删除指定表中的记录。这里假设我们只希望在删除数据时,只删除DetailTable数据表中的记录,而希望保留MainTable表中的记录,步骤如下:
  1. 新建一个工程,命名为Project2.dpr。
  2. 在主窗体中放置如下的组件:
  TAdoConnection:连接到SQL SERVER的数据库
  TAdoDataSet:设置其Connection属性为上一步中的TAdoConnection组件,并设置其CommandText属性为两个表连接查询的SQL语句,比如:
  select a.EmpId, a.EmpName, a.EmpOffice, b.OrderId,b.OrderName from MainTable a join DetailTable b on a.Emp
  Id=b.EmpId
  TDataSource:设置其DataSet属性为上一步的TAdoDa
  taSet组件。
  TDBNavigator 、TDBGrid:设置其DataSource属性为上一步的TDataSource组件。
  3. 在主窗体的OnCreate事件处理函数中编写代码:
  procedure TForm1.FormCreate(Sender: TObject);
  Var
  MyPty :Property_;
  MyPties :Properties;
  MyRS :_RecordSet;
  begin
  AdoTable1.Open; //打开数据集
  MyRS :=AdoDataSet1.RecordSet; //获取TAdoDataSet1组件封装的原生的ADO对象RecordSet
  MyPties :=MyRS.Properties; //通过原生ADO对象获取Properties动态属性集合
  MyPty :=MyPties.Get_Item('Unique Table').Value := 'Detail
  Table'; //通过动态属性集合的Get_Item函数获取其中的动态属性Unique Table的Value值。
  //AdoDataSet1.Recordset.Properties.Get_Item('Unique Table'
  ).Value := 'DetailTable'; 这一句的功能和上面各句是一样的。
  End;

http://www.sq120.com/Get/jiqiao/195837523_2.htm

标签: ,

Delphi下的ADO

Delphi下的ADO

ADO的精髓在于利用简单的COM指令来快速方便的访问ODBC数据源,微软的表格、列表框等ActiveX控件使得用户可以简便的利用ADO工作;然而,本文中笔者仅仅向您展示了如何利用程序访问数据库,将不采用任何可视化数据控件。
本文将向您展示如何利用Variant或interfaces访问和修改ADO数据库,示例程序非常简单,可运行于Delphi 3或4。
安装和访问一个ADO数据库。
示例程序的代码不足150行,然而运行本程序必须首先安装ADO以及设置ODBC数据源。
ADO是一组COM组件的集合,允许程序员利用利用少量的简单代码访问数据库。
ADO通常和OLEDB、Universal Data Access以及Microsoft Data Access Components(MDAC)联系在一起。OLEDB产生较ADO为早,是后期各种技术的基础。
如果你已经安装了ADO,你会在你的计算机中发现ADODB.DLL或者是MSADO15.DLL,这些文件中包含了一个类库,其中包括了利用ADO编程 所需的全部接口和常量。在Delphi中,选择菜单Project | Import Type Library,选择以上的DLL文件,然后确定,系统生成了一个基于ADODB.DLL的ADODB_TLB.Pas文件,这个文件中包含了所有 Delphi ADO编程所需的声明。
最后一步的准备工作就是将Delphi演示数据库中的Clients.DBF设置为ODBC系统DSN,其别名为DBDemosDBase,驱动程序为Dbase 5。
以下程序清单同时利用Variants和Interfaces访问ADO:
unit Main;
{---------------------------------------------------------------------
Created Jan 5, 1999. Copyright (c) 1999 by Charlie Calvert
----------------------------------------------------------------------}
interface


uses Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ComObj, Grids, ADODB_TLB, ExtCtrls;


const
SELECTSTRING = 'SELECT * FROM Clients.dbf';
DSNSTRING = 'DBDemosDBase';
type TForm1 = class(TForm)
StringGrid1: TStringGrid;
Panel1: TPanel;
VariantBtn: TButton;
InterfaceBtn: TButton;
UpdateBtn: TButton;
Edit1: TEdit;
procedure VariantBtnClick(Sender: TObject);
procedure InterfaceBtnClick(Sender: TObject);
procedure UpdateBtnClick(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);

private
procedure Display(RecordSet: _RecordSet); { Private declarations }
public { Public declarations }
end;
var Form1: TForm1;implementation
uses
ActiveX;
{$R *.DFM}
procedure TForm1.Display(RecordSet: _RecordSet);
var
Y, i: Integer;
begin
Y := 1;
repeat
for i := 0 to 6 do
StringGrid1.Cells[i, Y] := RecordSet.Fields[i].Value;
RecordSet.Move(1, EmptyParam);
Inc(Y);
until RecordSet.EOF;
end;
procedure TForm1.InterfaceBtnClick(Sender: TObject);
var RecordSet: _RecordSet;
DSN: string;
begin
// 生成空的recordset object
OleCheck(CoCreateInstance(CLASS_RecordSet, nil,
CLSCTX_ALL, IID__RecordSet, RecordSet));
DSN := 'dsn=' + DSNSTRING;
// 填写数据
RecordSet.Open(SelectString, DSN, adOpenForwardOnly,
adLockReadOnly, adCmdUnspecified);
// 显示数据
Display(RecordSet);
UpdateBtn.Enabled := True;
end;
procedure TForm1.UpdateBtnClick(Sender: TObject);
var RecordSet: _RecordSet;
DSN: string;
begin
OleCheck(CoCreateInstance(CLASS_RecordSet, nil,
CLSCTX_ALL, IID__RecordSet, RecordSet));
DSN := 'dsn=' + DSNSTRING;
// Fill the recordset
RecordSet.Open(SELECTSTRING, DSN, adOpenDynamic,
adLockOptimistic, adCmdUnspecified);
// 修改
RecordSet.Move(StringGrid1.Row - 1, EmptyParam);
RecordSet.Fields[StringGrid1.Col].Value := Edit1.Text;
RecordSet.Update(EmptyParam, EmptyParam);
RecordSet.MoveFirst;
Display(RecordSet);
end;
procedure TForm1.VariantBtnClick(Sender: TObject);
var
RecordSet: OleVariant;
Y, i: Integer;
begin
// Create an empty recordset object
RecordSet := CreateOleObject('ADODB.Recordset');
// Fill the recordset
RecordSet.Open(SELECTSTRING, DSNSTRING);
// Display the data
Y := 1;
repeat
for i := 0 to 6 do
StringGrid1.Cells[i, Y] := RecordSet.Fields[i].Value;
RecordSet.Move(1);
Inc(Y);
until RecordSet.EOF;
end;
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
Edit1.Text := StringGrid1.Cells[ACOl, ARow];
end;
end.
这个程序有三个按钮,一个StringGrid以及一个编辑框,第一个按钮利用以Variants连接的ADO填充表格,第二个则利用Inteface进行连接。
第三个按钮用于修改数据,当用户单击StringGrid的单元格时,单元格中的数据会显示于编辑框中,可以修改编辑框中的数据,然后单击这个按钮,将会修改这个单元格以及数据库中的数据。
ADO中含有许多不同的对象,本文将集中讲述RecordSet和Fields这两个对象。
可以用如下的代码生成一个RecordSet的实例:
var
RecordSet: OleVariant;
begin
RecordSet := CreateOleObject('ADODB.Recordset');
... // Code omitted here
end;
CreateOleObject声明于ComObj.Pas中。它是ActiveX.Pas中的核心函数CoCreateInstance的一个简单包装。
要打开数据库,可利用以下代码:
const
SELECTSTRING = 'SELECT * FROM Clients.dbf';
DSNSTRING = 'DBDemosDBase';

begin
RecordSet := CreateOleObject('ADODB.Recordset');
RecordSet.Open(SELECTSTRING, DSNSTRING);
.. // Code omitted here
end;
Open方法有很多参数,但是在这个程序中我们只处理其中的两个。第一个是我们要执行的SQL语句,第二个是我们要操作的数据库。
当打开一个数据集时,数据集游标位于第一个记录,可以用下面的代码访问这个记录:

MyString := RecordSet.Fields[0].Value;
MyString := RecordSet.Fields[1].Value;

要移动游标,可以用RecordSet对象的Move方法:
RecordSet.Move(1);

利用Interface访问ADO:

利用Interface访问ADO的步骤同从前的例子大致相同:

procedure TForm1.InterfaceBtnClick(Sender: TObject);
var RecordSet: _RecordSet;
DSN: string;
begin
// Create an empty recordset object
OleCheck(CoCreateInstance(CLASS_RecordSet, nil,
CLSCTX_ALL, IID__RecordSet, RecordSet));
DSN := 'dsn=' + DSNSTRING;
// Fill the recordset
RecordSet.Open(SelectString, DSN, adOpenForwardOnly,
adLockReadOnly, adCmdUnspecified);
// Display the data
Display(RecordSet);
UpdateBtn.Enabled := True;
end;

同前一节的代码不同,这些代码必须包含ADODB_TLB.PAS。
这一段代码用ADODB_TLB.PAS中声明的_RecordSet代替了Variants。
这 里直接调用了CoCreateInstance来生成对象的实例。第一个参数传递了声明于ADODB_TLB.PAS中的常量 CLASS_RecordSet,它代表RecordSet的Class ID,第四个参数为IID__RecordSet,也是声明于ADODB_TLB.PAS中的,注意,它带有两条下划线!最后一个参数是我希望建立的实 例。
当调用recordSet.Open的时候,应该穿第五个参数。
const
SELECTSTRING = 'SELECT * FROM Clients.dbf';
DSNSTRING = 'DBDemosDBase';

begin
.. // Code omitted
DSN := 'dsn=' + DSNSTRING;
RecordSet.Open(SelectString, DSN, adOpenForwardOnly,
adLockReadOnly, adCmdUnspecified);
.. // Code omitted
end;
在前一节的例子中,可以只传递两个参数,这是因为Variants允许忽略参数,这时采用缺省值。当采用Interfaces时,则必须明确的定义参数。如果希望采用缺省值,则可以向下面这样调用函数:
RecordSet.Open(SelectString, DSN, EmptyParam, EmptyParam, EmptyParam);
在这里我们使用了EmptyParam这样一个Variant,它被声明于System.Pas,这些参数将采用缺省值。上面的例子中我用了声明于ADODB_TLB.PAS中的真正的缺省值。此类问题可参考Data Access SDK中的相关文件。
打开数据集以后,就可以用同上一节相同的方法显示数据。唯一的不同就是RecordSet.Move方法要有两个参数。
procedure TForm1.Display(RecordSet: _RecordSet);
var Y, i: Integer;
begin
Y := 1;
Repeat
for i := 0 to 6 do
StringGrid1.Cells[i, Y] := RecordSet.Fields[i].Value;
RecordSet.Move(1, EmptyParam);
Inc(Y);
until RecordSet.EOF;
end;

修改数据
当修改数据时,不能用打开数据集时使用的缺省值,而是应该传递以下的参数:
const
adOpenDynamic = $00000002;
adLockOptimistic = $00000003;
adCmdUnspecified = $FFFFFFFF;
begin
.. // Call CoCreateInstance
DSN := 'dsn=' + DSNSTRING;
RecordSet.Open(SELECTSTRING, DSN, adOpenDynamic, adLockOptimistic,
adCmdUnspecified);
.. // Code ommitted here
end;

无论你用的是Variants还是Interfaces,这段代码都将正常工作。
当你的数据集以可读写的方式打开时,如adLockOptimistic方式,就可以修改数据库的内容了:
RecordSet.Fields[0].Value := Edit1.Text;
RecordSet.Update(EmptyParam, EmptyParam);
这段代码可以修改当前记录的内容。当然也可以利用字段数组以及Move方法修改任何记录。如果用的是Variants方式,可以不传递任何参数。
在例子中,我采用了一种简单的方法来编辑表中的字段。如果用户在某一个字段商单击,其数值会显示于编辑框中:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
Edit1.Text := StringGrid1.Cells[ACOl, ARow];
end;

用于更新数据的代码如下:
RecordSet.Move(StringGrid1.Row - 1, EmptyParam);
RecordSet.Fields[StringGrid1.Col].Value := Edit1.Text;
RecordSet.Update(EmptyParam, EmptyParam);

第一行将数据集游标移动到表格当前行,第二行修改数据,第三行提交修改。
最后一步将把数据集游标移动到第一条记录,然后调用相同的过程显示修改后的数据库。
RecordSet.MoveFirst;
Display(RecordSet);
////////////////////////////////////////////////////
Delphi 5 ADO

关键词:Delphi - MIS

ADO
Universal Data Access (UDA)是微软公司策畋一部分,提供了快速访问各种数据库的能力,UDA提供了一种不受限制的能力,通过易用的API接口访问各种数据源,当然,这需要 与其兼容的驱动程序,类似Delphi的BDE,这项技术能在一个程序中从多样的数据源中轻易的访问到数据。UDA用MDAC来实现,而MDAC则包括 Active Data Objects(ADO),Open Database Connectivity(ODBC)与OLE DB.
ADO是MDAC的应用程序设计接口,OLE DB则是系统级的接口,定义了一套COM接口,提供了从关联数据库及文件系统的数据访问能力,ODBC为了向后兼容也包含在MDAC中,但是在将来,他要 被OLE DB所替代,现在对于ODBC,开发者通过ADO来使用ODBC驱动,尽管如此,OLE DB已经可用于Microsoft Access,Microsoft SQL以及Oracle.
ADO另外的一个重要的优势是将被内置在微软将的所有操作系统不,包括Windows 2000,这就意味着虽然现在为了使用ADO来访问数据库而不得不在每一台PC中安装ADO,而将来这种安装技术将消失。如果想进一步学习UDA及 ADO,可以访问微软的数据访问主页http://www.microsoft.com/data/default.htm,从这个主页上,不但可以载到 ADOredistributable,用他可以在windows95/98/nt安装ADO,也能得到MDAC的SDK,包含了完整的文档以及需要开发 自己的OLE DB 的所有工具,此外,SDK也包含ADO的发行版。
用ADO需要的每一件事,都被制作在Delphi 5的安装盘上,如果安装MDAC,进行MDAC目录,执行程序MDAC_TYP.EXE即可.由于安装程序仅为一个文件,所以安装MDAC也变得非常简 单。如果自己开发的应用程序需要安装MDAC,则此安装程序还可作为自己开发应用的安装程序的一部分,为了去除它的安装提示信息,需要在自制安装程序时使 用如下的命令行:mdac_typ.exe /q:a /c:"setup.exe /qt"
对于更多的安装MDAC的信息,象文件列表及依赖关系,可以看MDAC SDK文档。

使用ADOConnection 和 ADODataSet控件
D5提供了一套新的控件以支持ADO,并且能够轻易的转换现有的应用到ADO,要建立一个ADO应用,首先需要在form或data module中放一个ADOConnection控件,这与BDE 的Database 控件差不多,他允许通过ConnectionString属性定义与数据库的联接,如果想手工建立这个联接串可不是一件容易的事,这个串是由';'隔开的 一系列参数,这些参数很容易就能超过150个字符,幸运是是,微软提供了一个联接串编辑器,使做起这件事来变得简单。为了打开这个编辑器,就可完成这项工 作。爽的很。
在这个编辑器中,可以以两种方式之一来选择与数据源的建立,其一是用联接文件的方式,另一种则是建立联接串的形式,默认的情况下是使用联接串,选择 build按钮,出现数据联接属性设置对话框,在provider页,可以选择使用的驱动程式,当确定使用的驱动程序后,可以选择下一步,确定具体要联接 的数据库,需要注意的是,选择不同的驱动程序,在这一页需要确定的参数是不同的。当确定这里的各个参数后,可以用测试联接按钮来测试数据库是否可以联接, 从而确定给定的联接参数是否正确。在这里,我们仅以Microsort Jet 4.0为例子,联接本地的一个Acess表。
现在,当完成联接串后,就可以设置Connected为True,使ADOConnection与数据库真正的联接。此时,可以放置ADODataset 控件,实际上,只有ADODataset才是真正与数据一起工作的,通过ADODataset,可以直接与一个表进行联接,也可以执行SQL语句,还可以 执行存储过程(哇,好利害)。使用ADODataset的第一步,就是设置Connection,确定其使用那一个ADOConnection,接下来, 要处理两个有关联的属性:CommandType与CommandText,由于CommandText是由commandtype决定的,所以要先设置 commandType,正是由他来决定DataSet怎样与数据库工作,用表,SQL还是存储过程。而后CommandText自然就容易设置,不用多 说。当这两个参数确定下来,余下的工作就如同原来的使用BDE访问数据库的工作差不多,使用DataSource与ADODataSet联接,与就是用 DBGrid等与DataSource联接,现在,利用ADO,可以访问到数据了!

http://www.delphichm.com/html/Database/aaaafsdfasdf/20070622/40.html

标签: ,

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger