求助,Delphi中数据字段类型同原生ADO中字段类型的对应关系

如题所述

我发现很多朋友在开发数据库时都使用 Delphi 自带的 ADO 组件 或 Diamond ADO,其实在 Delphi 中使用原生 ADO 接口也是十分方便和有效的。我使用原生 ADO 开发项目已有很长一段时间,也回答过一些朋友类似的问题,现在把自己的一点心得与大家分享,班门弄斧,只是希望能对大家有所帮助。当然,这帖子也是原生的,不是转贴的。
一、优点
1、大家知道 Delphi 对 ADO 接口进行了一番包装后形成了 ADOExpress,我想 Borland 的主要目的还是想与自己的数据敏感控件相连。然而事实上数据敏感控件并不是那么耀眼,如果你希望你编出来的程序稍微有点水准的话那就别用那玩意;如果你很少使用数据敏感控件,那么 ADOExpress 基本上失去了其应有的作用,无数冗余的属性、虚方法,不管你用不用得到一股脑给你编译进去,也会使你的程序再大上 200K;效率么,不说了。
2、MSDN 和 VB 中的例子你可以搬过来就用。
3、告诉那些 Delphi 反对者,Delphi 不是离开组件就活不了。
4、关于代码重用:我给大家的例子都是以函数或过程形式,重用性不好么?
5、别说帖子太长,那你看看 DB.pas, ADODB.pas 多长?
二、基本储备
1、一些必须的单元
uses
Variants, ComObj;
2、一些基本常数(其它查 ADODB2000.pas):
const
adOpenDynamic = $00000002;
adOpenStatic = $00000003;
adLockOptimistic = $00000003;
adLockBatchOptimistic = $00000004;
adStateClosed = $00000000;
adStateOpen = $00000001;
adStateConnecting = $00000002;
adStateExecuting = $00000004;
adStateFetching = $00000008;
adUseServer = $00000002;
adUseClient = $00000003;
adModeReadWrite = $00000003;
adXactCursorStability = $00001000;
adCmdText = $00000001;
adCmdTable = $00000002;
adCmdStoredProc = $00000004;
adCmdFile = $00000100;
adAffectCurrent = $00000001;
adAffectGroup = $00000002;
adAffectAll = $00000003;
adAffectAllChapters = $00000004;
3、一些基本函数和过程
//创建 Connection 对象
function CreateConnection: OleVariant;
//释放 Connection 对象;cnn 为 Connection 对象
procedure FreeConnection(var cnn: OleVariant);
//创建 Recordset 对象
function CreateRecordset: OleVariant;
//释放 Recordset 对象;rst 为 Recordset 对象
procedure FreeRecordset(var rst: OleVariant);
//创建 Command 对象
function CreateCommand: OleVariant;
//释放 Command 对象;cmd 为 Command 对象
procedure FreeCommand(var cmd: OleVariant);
//用 Connection 连接到 SQLServer 数据库;cnn 为 Connection 对象,db 数据库名,host 主机名,usr 用户名,pwd 密码
function ConnectToDB(cnn: OleVariant; const db, host, usr, pwd: string): Boolean;
//执行 SQL 语句,有返回行,无事务处理;cnn 为 Connection 对象,rst 为 Recordset 对象,sql 为 SQL 语句(可以是存储过程)
function ExecSQL(cnn, rst: OleVariant; const sql: string): Boolean;
//执行 SQL 语句,无返回行,有事务处理;cnn 为 Connection 对象,cmd 为 Command 对象,sql 为 SQL 语句(可以是存储过程)
function ExecSQLA(cnn, cmd: OleVariant; const sql: string): Boolean;
function CreateConnection: OleVariant;
begin
try
Result := CreateOleObject('ADODB.Connection');
Result.CursorLocation := adUseServer;
Result.IsolationLevel := adXactCursorStability;
Result.Mode := adModeReadWrite;
Result.Provider := 'SQLOLEDB.1';
except
if not VarIsEmpty(Result) then Result := Unassigned;
end;
end;
procedure FreeConnection(var cnn: OleVariant);
begin
if not VarIsEmpty(cnn) then
begin
if cnn.State <> adStateClosed then cnn.Close;
cnn := Unassigned;
end;
end;
function CreateRecordset: OleVariant;
begin
try
Result := CreateOleObject('ADODB.Recordset');
Result.CacheSize := 1000;
Result.CursorType := adOpenStatic;
Result.CursorLocation := adUseServer;
Result.LockType := adLockOptimistic;
except
if not VarIsEmpty(Result) then Result := Unassigned;
end;
end;
procedure FreeRecordset(var rst: OleVariant);
begin
FreeConnection(rst);
end;
function CreateCommand: OleVariant;
begin
try
Result := CreateOleObject('ADODB.Command');
Result.CommandType := adCmdText;
Result.CommandTimeout := 5;
except
if not VarIsEmpty(Result) then Result := Unassigned;
end;
end;
procedure FreeCommand(var cmd: OleVariant);
begin
if not VarIsEmpty(cmd) then cmd := Unassigned;
end;
function ConnectToDB(cnn: OleVariant; const db, host, usr, pwd: string): Boolean;
begin
Result := not VarIsEmpty(cnn);
if Result then
begin
if cnn.State <> adStateClosed then cnn.Close;
cnn.ConnectionString :=
'Provider=SQLOLEDB.1;Persist Security Info=True;Initial Catalog=' +
db + ';Data Source=' + host + ';Connect Timeout=5;' +
'Use Procedure for Prepare=1';
try
cnn.Open(cnn.ConnectionString, usr, pwd, -1);
except
Result := False;
end;
end;
end;
function ExecSQL(cnn, rst: OleVariant; const sql: string): Boolean;
begin
Result := not (VarIsEmpty(cnn) or VarIsEmpty(rst)) and (cnn.State = adStateOpen);
if Result then
begin
if rst.State <> adStateClosed then rst.Close;
try
rst.Open(sql, cnn, adOpenStatic, adLockOptimistic, adCmdText);
except
Result := False;
end;
end;
end;
function ExecSQLA(cnn, cmd: OleVariant; const sql: string): Boolean;
begin
Result := not (VarIsEmpty(cnn) or VarIsEmpty(cmd)) and (cnn.State = adStateOpen);
if Result then
begin
cnn.BeginTrans;
try
cmd.ActiveConnection := cnn;
cmd.CommandText := sql;
cmd.Prepared := True;
cmd.Execute;
cnn.CommitTrans;
except
cnn.RollbackTrans;
Result := False;
end;
end;
end;
三、访问数据
1、最前 rst.MoveFirst;
2、最后 rst.MoveLast;
3、向前 rst.MovePrevious;
4、向后 rst.MoveNext;
5、取当前记录 rst.Fields[0].Value 或 rst.Fields['字段名'].Value;
6、修改当前记录 rst.Update(rst.Fields[0].Name, 某值);
7、取消修改 rst.CancelUpdate;
8、删除当前记录 rst.Delete(adAffectCurrent);
9、删除所有记录 rst.Delete(adAffectAll);
10、追加记录
rst.AddNew;
rst.Fields[0].Value := 值1;
rst.Fields[1].Value := 值2;
rst.Update;
11、刷新 rst.Refresh;
12、记录数 rst.RecordCount
15、其它方法和属性查 MSDN 或 ADO 的帮助;
四、一些例子
//变量声明
var
cnn, rst, cmd: OleVariant;
//创建对象
procedure TForm1.FormCreate(Sender: TObject);
begin
cnn := CreateConnection;
rst := CreateRecordset;
cmd := CreateCommand;
end;
//释放对象
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeCommand(cmd);
FreeRecordset(rst);
FreeConnection(cnn);
end;
//连接数据库
procedure TForm1.Button1Click(Sender: TObject);
begin
if ConnectToDB(cnn, 'mydb', '127.0.0.1', 'sa', 'ok') then
Caption := '连接成功'
else Caption := '连接失败';
end;
//取记录
procedure TForm1.Button2Click(Sender: TObject);
begin
ExecSQL(cnn, rst, 'select * from 表a');
Caption := VarToStr(rst.Fields['字段a'].Value);
end;
五、原生 ADO 与 Delphi ADOExpress 组件的对应关系
1、Connection <=> ADOConnection.ConnectionObject;
2、Recordset <=> ADODataSet.Recordset;
3、Command <=> ADOCommand.CommandObject;
4、? <=> ADOQuery,因为 ADOQuery 根本就不是原生 ADO 对象
5、ExecSQL <=> ADODataSet.Open;
6、ExecSQLA <=> ADOCommand.Execute;
7、有了上面几个其它的就不多说了
六、与数据库结构有关的一些函数
1、动态改变字段名称
uses ComObj;
//Access
//TableName: 表名; OldColName: 原字段名; NewColName: 新字段名;
procedure RenameField(const TableName, OldColName, NewColName: string);
var
DB, Col: OleVariant;
begin
DB := CreateOleObject('ADOX.Catalog');
DB.ActiveConnection := ADOConnection1.ConnectionObject;
Col := CreateOleObject('ADOX.Column');
Col := DB.Tables[TableName].Columns[OldColName];
Col.Name := NewColName;
end;
//SQLServer
procedure RenameField(const TableName, OldColName, NewColName: string);
begin
with ADOCommand1 do
begin
CommandText := 'EXEC sp_rename ''' + TableName + '.' + OldColName +
''',''' + NewColName + ''',''COLUMN'';';
Excute;
end;
end;
2、取得 Access 库中的表结构
type
TTableDef = record
Name,
DateCreated,
LastUpdated,
Description: string;
end;
TTableDefs = array of TTableDef;
procedure GetTableDefs(const DBName: string; out TableDefs: TTableDefs);
var
DBEngine, DB: OleVariant;
I: Longint;
begin
try
DBEngine := CreateOleObject('DAO.DBEngine.36');
DB := DBEngine.OpenDatabase(DBName);
SetLength(TableDefs, Longint(DB.TableDefs.Count));
for I := Low(TableDefs) to High(TableDefs) do
begin
TableDefs[I].Name := DB.TableDefs[I].Name;
TableDefs[I].DateCreated := DB.TableDefs[I].DateCreated;
TableDefs[I].LastUpdated := DB.TableDefs[I].LastUpdated;
try
TableDefs[I].Description := DB.TableDefs[I].Properties['Description'].Value;
except
TableDefs[I].Description := '';
end;
end;
finally
DB := Unassigned;
DBEngine := Unassigned;
end;
end;
3、取得 Access 表中的字段结构
type
TFieldDef = record
Name: string;
Types,
Size: Longint;
Description: string;
end;
TFieldDefs = array of TFieldDef;
procedure GetFieldDefs(const DBName, TableName: string; out FieldDefs: TFieldDefs);
var
DBEngine, DB: OleVariant;
I: Longint;
begin
try
DBEngine := CreateOleObject('DAO.DBEngine.36');
DB := DBEngine.OpenDatabase(DBName);
SetLength(FieldDefs, Longint(DB.TableDefs[TableName].Fields.Count));
for I := Low(FieldDefs) to High(FieldDefs) do
begin
FieldDefs[I].Name := DB.TableDefs[TableName].Fields[I].Name;
FieldDefs[I].Types := DB.TableDefs[TableName].Fields[I].Type;
FieldDefs[I].Size := DB.TableDefs[TableName].Fields[I].Size;
try
FieldDefs[I].Description := DB.TableDefs[TableName].Fields[I].Properties['Description'].Value;
except
FieldDefs[I].Description := '';
end;
end;
finally
DB := Unassigned;
DBEngine := Unassigned;
end;
end;
4、至于如何动态创建 Access 数据库之类我就不罗嗦了,到处都有相关的月经贴
七、其它
1、我使用 ADO 的经历:ADOExpress-->ADOExpress的原生接口-->引用ADO2.1接口单元,即ADODB_TLB-->直接使用 ADO 的 COM 接口;
2、希望此贴能对朋友门有所帮助,我写的这些都是经过实战检验的;
3、觉得有用的朋友可以试一下,如果觉得没用就当我没写,耽误你时间了。
温馨提示:内容为网友见解,仅供参考
无其他回答

求助,Delphi中数据字段类型同原生ADO中字段类型的对应关系
五、原生 ADO 与 Delphi ADOExpress 组件的对应关系1、Connection <=> ADOConnection.ConnectionObject;2、Recordset <=> ADODataSet.Recordset;3、Command <=> ADOCommand.CommandObject;4、? <=> ADOQuery,因为 ADOQuery 根本就不是原生 ADO 对象 5、ExecSQL <=> ADODataSet.Open;6、ExecSQLA <=> ADOComma...

Delphi中ADOQuery1.FieldByName('列名').AsString='技改'和ADOQuery1...
区别:FieldByName可以AsString,AsInteger之类的,类型明确的赋值。FieldValues是对变体类(Variant)赋值。可以认为FieldByName('字段').Value := 123 和FieldValues['字段']:=123 是一个意思。

在Delphi中,ADOQuery和ADODataSet有什么不同
在 delphi 中,提供了以下 数据库 访问类型控件:1. TADOTable 组件:可以直接选择访问数据库中单个表的数据 2. TADOCommand:用于执行 SQL 命令 3. TADOStoredProc: 当需要执行存储过程时使用 4. ADOQuery:用 SQL 语句连接数据表,与 TADOTable 组件相比较,可以用 SQL 语句选择多表 ADOQuery 和...

Delphi DBGridEH 控件中输入显示的内容,怎么一一对应Insert到SQL数据库...
用adoquery 关联DBGRDEH,DBGRIDEH中的列通过field属性跟数据库中的列关联,保存的时候:adoquery.post

delphi7中 向adoquery中添加字段显示--操作数据类型冲突:text与smalldat...
数据库里的字段是smalldatetime,如果你向该字段下填写数据,应该是DateTime类型的数据!你这种现象应该是你把text类型数据没有转换成datetime型所至 stringtodatetime()..

delphi关于标准表达式中数据类型不匹配的问题
那你别变,直接 Parameters.Items[2].value:=Edit1.Text;这样试试 按理说转化了应该是对的 还有你的数据库中是int类型还是double类型 如果是int那你这句就有问题了

DELPHI给sql中的参数赋值ADOQUERY1.Parameters.ParamByName
xxx:= edit1. text是绝对不对的,因为左边是个parameter对象,右边是个string,类型是不匹配的,无法进行赋值。还是得用xx.value:=edit1. text,这是variant和string间的赋值操作,是允许的。你用的ADO,我猜你在.valur赋值时遇到的错误可能是参数类型不匹配或者是没有这个参数,你可以先通过...

麻烦请问用delphi的adoquery的sort排序的时候,怎么是给某一列的字符按...
.for i:=0 to v.Count-1 do begin sql:='INSERT INTO KKK (字段1, 字段2,...) select 原字段1,原字段2... from 原表 where 原字段1='''+V[i]+''';ADOQuery.close;ADOQuery.sql.text:=sql;ADOQuery.execsql;end;代码没有经过编译 不同数据库sql语句也不同 只供参考 ...

delphi7中DataSource1.DataSet不可选择为ADOQuery1
建议你仔细检查一下,是不是制定反了,因为datasource和adoquery是可以相互指定的,但是如果是已经在adoquery中指定了datasource的话,那么datasource就不能指定这个adoquery了

delphi中如何判断DBGrid中的同一列的值相同?
ADOQuery1.Close; \/\/一般情况下要先关闭 ADOQuery1.SQL.Clear; \/\/清除之前的查询内容 ADOQuery1.SQL.Add('select * from AA where BB='''+edit1.Text+'''); \/\/查询数据表中BB字段中有没有与Edit里输入内容相同的记录 ADOQuery1.Open;if ADOQuery1.RecordCount>0 then \/\/假如有记录则提...

相似回答