数据库组件及应用
使用 TTable可以通过 BDE访问数据库
中一张表中的数据。 Ttable提供对基础
数据库表中每一个记录和每一个域的
直接访问
数据集组件 -TTable
数据集组件 -TTable
Age>20 and dno=`d01`
True
数据集组件 -TQuery
TQuery 查询组件
一个查询组件封装了一个 SQL语句,该语句在客户
应用程序中用于在一个或多个数据库表中检索、插
入、修改和删除数据。因此,该组件实际上是为你
使用 SQL语句操纵数据库提供了一种手段。
数据集组件 -TQuery
Query1
Select *
from students
where dno=:dno
Select *
from student
where dno=:dno
Tquery - 参数动态赋值
with query1 do
begin
DisableControls;
try
Close;
ParamByName(`dno`).value:=` d01` ;
Open;
finally
EnableControls;
end;
end;
Dataset 方法
禁止通过数据源与该数据集组件相连
的数据感知控件显示数据,
Query1.Close;
Query1.ParamByName(`dno`).value:=` d01` ;
Query1.Open;
Tquery - 动态构造 SQL语句
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from students');
Query1.SQL.Add('where dno=''' +edit1.text +'''');
Query1.Open;
Query1.SQL.Add(`update …`);
Query1.ExecSQL;
Select * from student
where dno= ` d01 `
连续 2个上引号代表字符串中的一个上引号字符
理解数据集
TDataSet
TBDEDataSetTClientDataSet
TDBDataSet
TQueryTTable TStoredProc
Delphi 中访问数据库的基本单元是
数据集对象族。
应用程序对数据库的所有访问都是
通过数据集组件实现的。
通常,一个数据集对象代表一个数
据库中的一张具体的表,或代表访问
数据库的一个 DML语句,或存储过程。
理解数据集
理解数据集
?TDataSet 是所有数据集组件的一个基类,
它能表示数据库中二维表的数据(行、列)
?TDataSet 是一个抽象基类,它封装了一组
与数据库引擎无关的、涉及数据的属性、
事件和方法
属性
方法
事件





数据集常用操作
? 打开和关闭数据集
? 定位记录与检索记录
? 访问数据集
? 检查和设置数据集状态
? 编辑和修改记录
? 过滤数据集
打开、关闭数据集
? 设计时:
? 通过设置有关属性实现 。 如将 TTable的 Active
属性设为 True 或 False。
? 运行时
? 调用打开 /关闭方法
Table.Open Table.Close
定位数据集
? First 将指针移到数据集的第一行 。
? Last 将指针移到数据集的最后一行 。
? Next 将指针后移一行 。
? Prior 将指针前移一行 。
? MoveBy 将指针前移或后移指定的行 。
? Moveby(5)是后移 5行,
?Moveby(-2)是前移 2行 。
? BOF属性,True(指针在数据集第一行 ) ;
? EOF属性,True(指针在数据集最后一行 )
方法
Table1.DisableControls;
try
Table1.First;
While not Table1.EOF do
Begin
.,,
Table1.Next;
End;
Finaly
Table1.enableControls;
定位数据集
查找记录- locate方法
procedure TForm1.Button1Click(Sender,TObject);
var
loc, boolean;
locOp,TlocateOptions;
begin
locOp,= [lopartialkey,locaseinsensitive];
loc:=table1.locate(`sname`,edit1.text,locop);
end;
部分匹配 不区分大小写
列名 列值 查找选项
访问数据集 - 动态字段
?针对 Ttable和 Tquery(select … )
?是 Delphi 根据数据集自动生成,并由 Delphi 根据
数据集的变化进行维护。
?动态字段对象访问
通过下标访问动态字段对象
property Fields[Index,Integer],TField ;
例;
Table1.Fields[1].DisplayLabel:='姓名 ' ;
Table1.Fields[1].Alignment:= tacenter ;
Edit1.text,= Table1.Fields[1].Value;
通过字段名访问动态字段对象
function FieldByName(const FieldName,string),TField;
例:
Table1,FieldByName('sname').DisplayLabel:='姓名 ' ;
Edit1.Text,=Table1,FieldByName('sname').value;
访问数据集 - 永久字段
动态字段的属性和可用性全是由 Delphi 自动设
置的, 不能以任何方式改变 。 要想在设计阶段获得
对字段的属性及事件的控制权, 必须为数据集建立
永久字段 。




访问数据集 - 永久字段
? 永久字段值访问
?Edit1.Text,= Table1Sname.Value;
?Edit1.Text,= Table1Age.AsString ;
?Table1Age.AsString,= Edit1.Text;
? 字段值类型转换
?AsInteger
?AsFloat
?AsDataTime
数据集状态转换图
数据集修改 ?数据库
? Post方法
是 Delphi 应用程序与数据库表交互的核心 。 Post
将数据集中的数据变化写入数据库:
?在 dsEdit状态下, 是将已修改的记录写入数据

?在 dsInsert状态下, 是将新插入的记录写入数
据库 。
修改 记录
?修改记录字段
Table1.Edit ;
Table1.FieldByName('age’).value:=22 ;
Table1.Post ;
?修改整条记录
With Table1 do
Begin
Edit ;
SetFields(nil,`计算机科学系 `,2288);
Post
End ;
Null 空值
nil 保持不变
插入、删除记录
? table1.InsertRecord([980001,`c01`,NULL]) ;
? Table1.Delete
? 隐式执行 Post
插入,修改和 删除记录
数据感知
控件 Table1
方法
post
table1.InsertRecord
table1.Delete
Query1 Insert into dep values… delete from dep …
数据集事件
procedure TForm3.Table1BeforeDelete(DataSet,TDataSet);
begin
if messagedlg('删除该记录? ',mtconfirmation,
[mbyes,mbno],0) <> mryes then
abort;
end;
在任何 Before方法中,通过调用
一个 Abort过程,可以终止一个
方法
习题 3-主界面
Form2.showmodal
习题 3-查询界面
查询界面
dep
editdno
SQL
editnum
Table1
DBGrid Table2
DBNavigator
Dnoselect count(*)
from students
where dno=,dno ;
procedure TForm2.Table1AfterScroll(DataSet,TDataSet);
begin
query1.close;
query1.ParamByName('dno').value:=editdno.Text;
query1.Open;
editnum.text:=query1.fields[0].asString;
end;
student
维护界面
维护界面
procedure TForm3.Button1Click(Sender,TObject);
begin
table1.active:=false;
table1.tablename:=combobox1.Text;
table1.active:=true;
end;
选课界面
以表格形式显示字符串的控件
StringGrid (1)
StringGrid (2)
? 表格单元的内容是通过属性 Cells的值来存取的。 Cells属性
是一个字符串型二维数组,数组的每一个元素代表了表格
的一个单元。数组下标都是从 0开始。如图中 `语文 `就是
StringGrid1.Cells[1,1]的内容。
? 属性 RowCount和 ColCount决定了表格的行, 列数 。 如本例
中它们的值分别是 5和 6。
? 属性 FixedRows和 FixedCols用来确定锁定的行数和列数 。
这些被锁定的行或列常用来作为标题栏, 它们不随单元的
滚动而滚动, 用光标也不能选中它们 。 本例中被锁定的行
和列数都是 1( 即第 0行和第 0列被锁定 ) 。
? StringGrid的一个基本事件就是 OnSelectCell,当鼠标选中
某个单元时, 该事件发生, 选中单元的坐标作为参数被传
送到事件处理程序中 。
StringGrid (3)
implementation
{$R *.DFM}
var
acol,arow,integer;
procedure TForm1.FormCreate(Sender,TObject);
begin
stringGrid1.Cells[0,1]:= '第一节 ' ; stringGrid1.Cells[0,2]:= '第二节 ' ;
stringGrid1.Cells[0,3]:= '第三节 ' ; stringGrid1.Cells[0,4]:= '第四节 ' ;
stringGrid1.Cells[1,0]:= '星期一 ' ; stringGrid1.Cells[2,0]:= '星期二 ' ;
stringGrid1.Cells[3,0]:= '星期三 ' ; stringGrid1.Cells[4,0]:= '星期四 ' ;
stringGrid1.Cells[5,0]:= '星期五 ' ;
acol:=1; arow:=1;
end;
当窗体建立时对 strintgrid1做 初始化工作
StringGrid (4)
procedure TForm1.StringGrid1SelectCell(Sender,TObject; Col,Row,
Integer; var CanSelect,Boolean);
begin
acol:=col;
arow:=row;
end;
procedure TForm1.Button1Click(Sender,TObject);
begin
stringGrid1.Cells[acol,arow]:=edit1.text;
end;
procedure TForm1.Button2Click(Sender,TObject);
begin
stringGrid1.Cells[acol,arow]:= ' ' ;
end;
填入课程
删除课程
当鼠标选择一个单元时,记下该单元坐标
StringGrid (5)
procedure TForm1.Button3Click(Sender,TObject);
var
i,j, integer ;
begin
for i:=1 to stringGrid1.ColCount-1 do
for j:=1 to stringGrid1.RowCount-1 do
stringGrid1.Cells[i,j]:= ' ' ;
end;
end.
全清课表
选课界面
5
432
1
Query2/5 封装的 SQL语句
? Query2.SQL
select cno,cname,ctime
from sc,course
where sno=:sno and grade is null and
sc.cno=course.cno;
? Query5.SQL
select count(*),sum(credit)
from sc,course
where sno=:sno and grade is null and
sc.cno=course.cno;
Query 1/3/4 封装的 SQL语句
? Query1.SQL属性初始为空
? query3.SQL
insert into sc(sno,cno)
values(:sno,:cno);
? Query4.SQL
delete from sc
where sno=:sno and cno=:cno ;
进入 `学号 `编辑框事件句柄
procedure TForm4.snoeditEnter(Sender,TObject);
var
i,j,integer ;
begin
snoedit.text:=''; snameedit.text:=''; oldcreditedit.text:='';
for i:=1 to 5 do
for j:=1 to 4 do
begin
stringGrid1.Cells[i,j]:= '' ;
acno[i,j]:='';
end;
query5.close;
selectBt.enabled:=false; delBt.enabled:=false;
end;
`输入确认 `按钮事件
implementation
{$R *.DFM}
var
acol,arow,integer;
acno,array[1..5,1..4] of string ;
snum, integer ;
procedure TForm4.verifyBTClick(Sender,TObject);
begin
try
snum:=strtoint(snoedit.text);
except
showmessage('输入有误 ');
exit ;
end; 3-1
`输入确认 `按钮事件
query1.close;
query1.sql.Clear;
query1.sql.add('select sname from student');
query1.sql.add('where sno='+snoedit.text);
query1.open;
if query1.fieldbyname('sname').asstring='' then
showmessage('学号有误 ')
else
begin
snameEdit.text:=query1.fieldbyname('sname').value;
query1.close;
query1.sql.Clear;
query1.sql.add('select sum(credit) from sc,course');
query1.sql.add('where sno=' + snoedit.text);
query1.sql.add('and sc.cno=course.cno and grade>=60');
query1.open;
oldcreditedit.text:=query1.Fields[0].asstring; 3-2
`输入确认 `按钮事件
query5.close;
query5.ParamByName(‘sno’).value:=snum; //选修门数和学分
query5.open;
query2.close;
query2.ParamByName(‘sno’).value:=snum; //选修课号课名时间
query2.open;
While not query2.EOF do
Begin
acol:=query2ctime.Value div 10 ;
arow:=query2ctime.value mod 10 ;
stringGrid1.Cells[acol,arow]:=query2cname.value ;
acno[acol,arow]:=query2cno.value;
query2.Next;
End;
selectBT.enabled:=true;
delBT.enabled:=true;
end ;
end; 3- 3
选课按钮代码
procedure TForm4.selectBTClick(Sender,TObject);
begin
if table1quota.value=0 then
begin
showmessage(‘没有名额’ ); exit;
end ;
acol:=table1ctime.value div 10;
arow:=table1ctime.value mod 10 ;
if stringGrid1.Cells[acol,arow]<>'' then
begin
showmessage(‘时间冲突’ ); exit;
end ;
try
query3.close;
query3.parambyname(‘sno’).value:=snum ; //插入选课记录 2-1
选课按钮代码
query3.parambyname('cno').value:=table1cno.value;
query3.execsql;
except
showmessage('该课程已修 ');
exit;
end;
stringGrid1.Cells[acol,arow]:=table1cname.value;
acno[acol,arow]:=table1cno.value;
Table1.Edit ;
Table1quota.value:=table1quota.value-1;
Table1.Post ;
query5.close;
query5.open;
end; 2-2
退选按钮代码
procedure TForm4.delBTClick(Sender,TObject);
begin
if stringGrid1.Cells[acol,arow]='' then
begin showmessage(‘请选择退选课程’ ); exit; end ;
query4.close;
query4.parambyname('sno').value:=snum;
query4.parambyname('cno').value:=acno[acol,arow];
query4.execsql;
table1.locate('cno',acno[acol,arow],[]);
Table1.Edit ;
Table1quota.value:=table1quota.value+1;
Table1.Post ;
stringGrid1.Cells[acol,arow]:='' ;
acno[acol,arow]:='' ;
query5.close;
query5.open;
end;
查找按钮代码
procedure TForm4.searchBTClick(Sender,
TObject);
begin
if not table1.locate(`cno`,SearchCnoEdit.text,[ ])
then
showmessage('指定的课号不存在 ');
SearchCnoEdit.text:='';
end;
初始化课表
procedure TForm4.FormShow(Sender,TObject);
begin
stringGrid1.Cells[0,1]:= '第一节 ' ;
stringGrid1.Cells[0,2]:= '第二节 ' ;
stringGrid1.Cells[0,3]:= '第三节 ' ;
stringGrid1.Cells[0,4]:= '第四节 ' ;
stringGrid1.Cells[1,0]:= '星期一 ' ;
stringGrid1.Cells[2,0]:= '星期二 ' ;
stringGrid1.Cells[3,0]:= '星期三 ' ;
stringGrid1.Cells[4,0]:= '星期四 ' ;
stringGrid1.Cells[5,0]:= '星期五 ' ;
snoedit.SetFocus;
end;
选择课表单元格事件句柄
procedure TForm4.StringGrid1SelectCell(Sender,TObject;
Col,Row,Integer; var CanSelect,Boolean);
begin
acol:=col;
arow:=row;
end;
插入记录
? table1.InsertRecord( [ strtoint(edit1.Text),
strtoint(edit2.Text),date+14 ] ) ;
? query1.close;
query1.SQL.Clear ;
query1.SQL.Add('insert into borrow') ;
query1.SQL.Add('values(' + edit1.Text +',') ;
query1.SQL.Add(edit2.text + ',sysdate)') ;
query1.ExecSQL ;
? 刷新(定义主码)