即:先用ADOConnection连接数据库,再用ADOQuery执行SQL语句,最后将返回的数据集填充到StringGrid
这样就获得了一张所需的数据表格。
一、环境
Windows10
RAD Studio 10 Seattle
SQL Server 2014 Management Studio
二、连接数据库
1、手动配置ADOConnection和ADOQuery连接数据库
①创建一个工程
File——New——VCLForms Application
创建一个工程,才能运行相应的form
②Form 中添加ADOConnection和ADOQuery控件
Tool Palette中搜索ADOConnection和ADOQuery
③双击ADOConnection配置数据库
- use connection string——build——提供程序——Microsoft OLE DB Provider for SQL Server
④ADOConnection配置数据库连接
- 本地连接的设置
- 服务器连接的设置
如果连接的数据库不是本地库,则在服务器名称处填写【服务器名称/服务器IP】
⑤ADOConnection数据库连接的字符串
我的主要是以链接本地数据库为例
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost
⑥将ADOQuery与ADOConnection关联起来
2、Form中写代码连接数据库
①创建工程和控件选择的方法和上面一样
不要手动配置连接
②在Form中添加一个Button
按钮用来测试连接语句是否已经成功链接本地数据库
③双击进入Button控件编写事件
procedure TForm1.Button1Click(Sender: TObject);
begin
//ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost';//这段链接字符串就是上面手动配置时生成的
ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost';//这段是用非win账户链接数据库
try
ADOConnection1.Open;
ShowMessage('数据库连接成功');
except
ShowMessage('数据库未连接成功');
end;
end;
④运行Form
快捷键:Shift+Ctrl+F9
⑤检测结果
点击Button1
三、StringGrid的数据填充
上面数据库连接成功后,就可以从数据库中取数出来填充到StringGrid控件中
1、Form中添加TStringGrid
可以看到,Grid里现在已有5行5列,这是因为在属性这边的ColCount=5,RowCount=5(ColCount列数,RowCount行数)
2、Button1中添加向StringGrid填充数据代码
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
//ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost';//这段链接字符串就是上面手动配置时生成的
ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost';//这段是用非win账户链接数据库
try
ADOConnection1.Open;
//ShowMessage('数据库连接成功');
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select user_names,user_sex,user_phone,user_email from user_info');
ADOQuery1.Open;
StringGrid1.ColCount:= ADOQuery1.FieldCount; //StringGrid的列数为ADOQuery打开表后获取的列数
StringGrid1.RowCount:= ADOQuery1.RecordCount; //StringGrid的行数为ADOQuery打开表后获取的行数
// for I := 0 to ADOQuery1.RecordCount-1 do //从0-ADOQuery打开表后获取的列数-1(从0开始,多了一次,多以要-1)
// begin
// StringGrid1.Cells[0,I] := ADOQuery1.FieldByName('user_names').AsString;
// StringGrid1.Cells[1,I] := ADOQuery1.FieldByName('user_sex').AsString;
// StringGrid1.Cells[2,I] := ADOQuery1.FieldByName('user_phone').AsString;
// StringGrid1.Cells[3,I] := ADOQuery1.FieldByName('user_email').AsString;
//
// ADOQuery1.Next;
// end;
I:=0;
ADOQuery1.First; //由首行开始
while not ADOQuery1.Eof do //Eof:当表数据没到尾部时执行循环
begin
StringGrid1.Cells[0,I] := ADOQuery1.FieldByName('user_names').AsString;
StringGrid1.Cells[1,I] := ADOQuery1.FieldByName('user_sex').AsString;
StringGrid1.Cells[2,I] := ADOQuery1.FieldByName('user_phone').AsString;
StringGrid1.Cells[3,I] := ADOQuery1.FieldByName('user_email').AsString;
I:=I+1;
ADOQuery1.Next;
end;
except
ShowMessage('数据库未连接成功');
end;
ADOConnection1.Close;
end;
上面的代码用了两种循环赋值方式,其实都大同小异,都是根据ADOQuery打开表后获取的数据去做判断。
-
Bof和Eof的属性
ADOQuery1.Bof:指示当前记录位置位于 Recordset 对象的第一个记录之前。
ADOQuery1.Eof:指示当前记录位置位于 Recordset 对象的最后一个记录之后。 -
运行结果
可以看到,表中列数不是5了,Grid中的列数和行数都和select语句查询出来的数据表一致。
( 但是有一个小问题,没有表头和表列的自增值计数,并且列宽也是固定的。)
3、方法一:先自定义表头和列数
双击StringGrid1,进入窗体的事件中
procedure TForm1.FormCreate(Sender: TObject);
begin
with StringGrid1 do
begin
ColCount :=4;//4列
RowCount :=2;//2行
StringGrid1.Cells[0,0] :='姓名';//第0列第0行的表头名称
StringGrid1.Cells[1,0] :='性别';
StringGrid1.Cells[2,0] :='电话';
StringGrid1.Cells[3,0] :='邮件邮件邮件邮件邮件';
ColWidths[0] := 100;//第0列的列宽
ColWidths[1] := 50;
ColWidths[2] := 150;
ColWidths[3] := 200;
end;
end;
- 运行
可以看到Form中的StringGrid1有了自定义表头。
但是,这样会有什么问题呢?1、当你列数很多的时候,比如有20列,你就得写20条代码去命名每一列,然后再写20行代码再去设置列宽。如果是桌面应用这样的软件的话,每次做一点小修改都得重新升级,是不是很麻烦?
还有,再次点击按钮后,会把表头覆盖掉,所以StringGrid1的赋值循环要跳过第0行,从第一行开始哦~
4、方法二:根据返回的数据表获取表头和行列数
上面说了,用自定义的表头,如果修改次数多的话就会很烦躁,还有一列列地循环获取数据要写的相同代码行也很多。
那么,就根据select后返回的数据表自动获取表头各列的名称,然后再循环每一个单元格进行数据填充。
procedure TForm1.Button1Click(Sender: TObject);
var
I,J,W : Integer;
begin
ADOConnection1.ConnectionString := 'Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=SQLTEST;Data Source=localhost';//这段是用非win账户链接数据库
try
//SQL语句的执行
ADOConnection1.Open;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select user_names,user_sex,user_phone,user_email from user_info');
ADOQuery1.Open;
//获取行列数
StringGrid1.ColCount:= ADOQuery1.FieldCount; //StringGrid的列数为ADOQuery打开表后获取的列数
StringGrid1.RowCount:= ADOQuery1.RecordCount+1; //StringGrid的行数为ADOQuery打开表后获取的行数,因为多了一行表头,多以要+1
//获取表头
for W := 0 to ADOQuery1.FieldCount-1 do //返回的表列数做循环
StringGrid1.cells[w,0] := ADOQuery1.Fields[w].FieldName;//返回的表相应列的表头名
//数据循环填充
for i := 1 to ADOQuery1.RecordCount do
begin
for j := 0 to ADOQuery1.FieldCount-1 do
begin
StringGrid1.Cells[j,i] := ADOQuery1.Fields.Fields[j].AsString;
end;
ADOQuery1.Next;
end;
except
ShowMessage('数据库未连接成功');
end;
ADOConnection1.Close;
end;
- 运行
返回的数据表连同表头一起填充到了StringGrid1中,用了行列数的两层循环就行了,SO~简洁。
但是,表头还是select出来的英文字段,这个在执行SQL语句时,将字段另设为中文就行了。
额…StringGrid的列自适应宽度比较麻烦,要是像TAdvStringGrid控件一样,用AutoSizeColumns(true)这一句就可以设置自适应宽度就好了,TAdvStringGrid控件也可以用AutoNumberCol(0)就设置首列的数自增长。
四、结束语
在同事“我是不会去搞这垃圾delphi”的每日愤懑之下,我:“没关系,我都可。”
虽然说,delphi现在已经有点“没落”了,但是,什么言语的共通性其实都差不多的。往粗略了说,无非都是连接数据库、对数据库执行增删改查。不管黑猫还是白猫,能抓到老鼠的就是好猫(溜~)
温故总能知新,加油!