Delphi中ADO查询多表更新单表解决方法

本文介绍了在Delphi中使用ADO操作多表时如何更新单表的方法,通过设置数据集字段的providerflags,避免提交多表相关语句,解决了因未设置导致的错误问题,实现了数据库操作的精细化控制。

学Delphi也好久了,但一直没怎么总结,这不好久没弄ADO了,趁这个星期一直看公司的代码,自己也来实践一下。以前一直用ADO操作单表,一直没怎么弄过ADO操作多表的程序,不自己实践一下还真不知道操作多表时有要注意的地方。下面是一个例子。

第一步,新建一个测试库Test,表结构如下:




第二步,新建一个Delphi应用程序,在界面上放置adoconnection和adoquery以及 datasource和DBGridEh等控件,截图如下:



dfm文件如下:

object Form1: TForm1
  Left = 328
  Top = 78
  Width = 601
  Height = 403
  Caption = '数据库操作'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object tlb1: TToolBar
    Left = 0
    Top = 0
    Width = 585
    Height = 25
    AutoSize = True
    ButtonHeight = 21
    ButtonWidth = 31
    Caption = 'tlb1'
    ShowCaptions = True
    TabOrder = 0
    Transparent = False
    object btnAdd: TToolButton
      Left = 0
      Top = 2
      Caption = '添加'
      ImageIndex = 0
      OnClick = btnAddClick
    end
    object btnDel: TToolButton
      Left = 31
      Top = 2
      Caption = '删除'
      ImageIndex = 1
      OnClick = btnDelClick
    end
    object btnEdit: TToolButton
      Left = 62
      Top = 2
      Caption = '修改'
      ImageIndex = 2
      OnClick = btnEditClick
    end
    object btnSave: TToolButton
      Left = 93
      Top = 2
      Caption = '保存'
      ImageIndex = 3
      OnClick = btnSaveClick
    end
  end
  object dbgrdhUser: TDBGridEh
    Left = 0
    Top = 25
    Width = 585
    Height = 340
    Align = alClient
    DataGrouping.GroupLevels = <>
    DataSource = ds1
    Flat = False
    FooterColor = clWindow
    FooterFont.Charset = DEFAULT_CHARSET
    FooterFont.Color = clWindowText
    FooterFont.Height = -11
    FooterFont.Name = 'MS Sans Serif'
    FooterFont.Style = []
    RowDetailPanel.Color = clBtnFace
    TabOrder = 1
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
    OnCellClick = dbgrdhUserCellClick
    Columns = <
      item
        EditButtons = <>
        FieldName = 'id'
        Footers = <>
        Visible = False
      end
      item
        EditButtons = <>
        FieldName = 'deptname'
        Footers = <>
        Width = 94
      end
      item
        EditButtons = <>
        FieldName = 'uname'
        Footers = <>
      end
      item
        EditButtons = <>
        FieldName = 'deptid'
        Footers = <>
        Visible = False
      end
      item
        EditButtons = <>
        FieldName = 'sex'
        Footers = <>
        KeyList.Strings = (
          '男'
          '女')
        PickList.Strings = (
          '男'
          '女')
        Width = 45
      end
      item
        EditButtons = <>
        FieldName = 'age'
        Footers = <>
      end
      item
        EditButtons = <>
        FieldName = 'job'
        Footers = <>
      end>
    object RowDetailData: TRowDetailPanelControlEh
    end
  end
  object ds1: TDataSource
    DataSet = ds2
    Left = 208
    Top = 64
  end
  object ds2: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 280
    Top = 200
    object intgrfldds2id: TIntegerField
      FieldName = 'id'
      Visible = False
    end
    object strngfldds2deptname: TStringField
      DisplayLabel = '部门名称'
      FieldName = 'deptname'
      LookupDataSet = qryTemp
      KeyFields = 'deptid'
      ProviderFlags = []
    end
    object strngfldds2uname: TStringField
      DisplayLabel = '用户名'
      FieldName = 'uname'
    end
    object intgrfldds2deptid: TIntegerField
      FieldName = 'deptid'
    end
    object strngfldds2set: TStringField
      DisplayLabel = '性别'
      FieldName = 'sex'
      Size = 5
    end
    object intgrfldds2age: TIntegerField
      DisplayLabel = '年龄'
      FieldName = 'age'
    end
    object strngfldds2job: TStringField
      DisplayLabel = '职业'
      FieldName = 'job'
    end
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = qry1
    Left = 208
    Top = 200
  end
  object con: TADOConnection
    LoginPrompt = False
    Left = 176
    Top = 304
  end
  object qry1: TADOQuery
    Connection = con
    Parameters = <>
    Left = 224
    Top = 304
    object intgrfldqry1id: TIntegerField
      FieldName = 'id'
    end
    object strngfldqry1deptname: TStringField
      DisplayLabel = '部门'
      FieldName = 'deptname'
      ProviderFlags = []
    end
    object strngfldqry1uname: TStringField
      DisplayLabel = '姓名'
      FieldName = 'uname'
    end
    object intgrfldqry1deptid: TIntegerField
      DisplayLabel = '部门id'
      FieldName = 'deptid'
    end
    object strngfldqry1sex: TStringField
      DisplayLabel = '性别'
      FieldName = 'sex'
    end
    object intgrfldqry1age: TIntegerField
      DisplayLabel = '年龄'
      FieldName = 'age'
    end
    object strngfldqry1job: TStringField
      DisplayLabel = '职业'
      FieldName = 'job'
    end
  end
  object qryTemp: TADOQuery
    Connection = con
    DataSource = ds1
    Parameters = <>
    Left = 424
    Top = 312
  end
end

第三步,编写简单的增删查改代码代码如下:

unit UnitTblOp;


interface


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ToolWin, DBGridEhGrouping, DB, GridsEh, DBGridEh,
  Provider, DBClient, ADODB;


type
  TForm1 = class(TForm)
    tlb1: TToolBar;
    btnAdd: TToolButton;
    btnDel: TToolButton;
    btnEdit: TToolButton;
    btnSave: TToolButton;
    dbgrdhUser: TDBGridEh;
    ds1: TDataSource;
    ds2: TClientDataSet;
    intgrfldds2id: TIntegerField;
    strngfldds2deptname: TStringField;
    strngfldds2uname: TStringField;
    intgrfldds2deptid: TIntegerField;
    strngfldds2set: TStringField;
    intgrfldds2age: TIntegerField;
    strngfldds2job: TStringField;
    DataSetProvider1: TDataSetProvider;
    con: TADOConnection;
    qry1: TADOQuery;
    intgrfldqry1id: TIntegerField;
    strngfldqry1deptname: TStringField;
    strngfldqry1uname: TStringField;
    intgrfldqry1deptid: TIntegerField;
    strngfldqry1sex: TStringField;
    intgrfldqry1age: TIntegerField;
    strngfldqry1job: TStringField;
    qryTemp: TADOQuery;
    procedure FormShow(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure btnDelClick(Sender: TObject);
    procedure btnEditClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure dbgrdhUserCellClick(Column: TColumnEh);
  private
    procedure ShowData;
    procedure FillDept;
  public


  end;


var
  Form1: TForm1;


implementation


{$R *.dfm}




const
  strsql='Provider=SQLOLEDB.1;Password=%s;Persist Security Info=True;User ID=%s;Initial Catalog=%s;Data Source=%s';




procedure TForm1.ShowData;
begin
   with qry1 do
   begin
     Close;
     sql.Clear;
     SQL.Text:='select b.deptname,a.* from tbl_user a left join tbl_dept b on a.deptid=b.deptid';
     Open;
   end;
   ds2.Close;
   ds2.Open;
end;


procedure TForm1.FormShow(Sender: TObject);
begin
  ShowData;
end;


procedure TForm1.btnAddClick(Sender: TObject);
begin
  ds2.Append;
end;


procedure TForm1.btnDelClick(Sender: TObject);
begin
  if ds2.IsEmpty then exit;
  ds2.Delete;
end;


procedure TForm1.btnEditClick(Sender: TObject);
begin
  ds2.Edit;
end;


procedure TForm1.btnSaveClick(Sender: TObject);
begin
 if ds2.State in [dsInsert,dsEdit] then
 begin
  ds2.Post;
 end;
  ds2.ApplyUpdates(-1);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  if not con.Connected then
  begin
    con.ConnectionString:=Format(strsql,['123456','sa','Test','.']);
    con.Open;
   // FillDept;
  end;
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
  if con.Connected then
    con.Close;
end;


procedure TForm1.FillDept;
begin
   with qryTemp do
   begin
     Close;
     SQL.Clear;
     SQL.Add('select *  from  tbl_dept');
     Open;
     First;
     while not eof do
     begin
       dbgrdhUser.FieldColumns['deptname'].PickList.Add(FieldByName('deptname').AsString);
       dbgrdhUser.FieldColumns['deptname'].KeyList.Add(IntToStr(FieldByName('deptid').AsInteger));
       Next;
     end;
   end;
end;


procedure TForm1.dbgrdhUserCellClick(Column: TColumnEh);
var
  index:integer;
begin
 ds2.Edit;
 ds2.FieldByName('deptid').AsInteger:=strtointdef(ds2.FieldByName('deptname').AsString,0);
 ds2.ApplyUpdates(-1);
end;

end.

end.

运行结果如图:



在ADO操作多数据时,默认ADO是要提交多个表相关的语句,因此必须设置数据集字段的providerflags字段,当将pfInput和pfInWhere字段设置为false后,这样就可以只提交单表数据。当没有设置时有可能会出现以下错误:


查看sql分析器原来是生成了以下语句,默认情况当添加修改和删除时,都会对tbl_user表和tbl_dept表生成语句,当没有对tbl_dept赋值时会报上面那个错误 。

解决方法一单表更新即选中数据集控件,然后选中不需要提交的字段,比如该例中是deptname字段,选中该字段然后进行相关属性的设置

  这样进行数据库的操作时只会生成tbl_user相关的sql语句,实现更新单表的目的。

delphi操作数据库相关的知识还有很多细节,需要慢慢研究。欢迎同道中人多多指教。


数据库联查小程序-说明 这是一个数据库一起查询的小程序,主要缓解系统中报设计中只读取一个的问题。和对SQL语句不太会用的朋友查询之用。由于这是小程序,功能没有太,只能查询,不能修改数据库。这个软件还有很足之处,敬请谅解。“如SQL语句出错但没有提示是什么错误。”“不能保存,已经生成的语句。(但可以手动复制TXT文本出来。)”“不能和报软件有机结合”等等。 由于时间及所学知识有限问题。暂时只能做到这个样子。下一步将与Grid++Report 报设计器(可以在http://yunpan.cn/QUXEFX4nSaQXv 这里下载)的软件结合,做到一体化。这样以后就不用担心系统软件的报功能不能满足行业需求了! 这是一个数据库一起查询的小程序,主要缓解系统中报设计中只读取一个的问题。和对SQL语句不太会用的朋友查询之用。由于这是小程序,功能没有太,只能查询,不能修改数据库。 使用方法: 1. 首先点,“1.连接数据库”按键,连接数据库。 2. 3. 出现如下窗口,点击Build按钮 图 3 4 选择如下图标示项,并点击下一步 图 3 5 如下图,第一项选择你需要的SQL服务器,第二项如选择使用windows集成安全设置则不需要输入用户名及密码,选择使用指定的用户名和密码是则需要输入已在数据库中建立的用户名和密码,当第二项设置正确时第三项的在服务器上选择数据库的下拉项中会出现你所选择的数据库服务器上的所有可用数据库,选择你所需要的数据库即可。 图 3 6 设置完成后点击测试连接按钮,出现如下图画面时数据库连接成功可以点确定结束设置。 图 3 7 二,读。 三、单击数据库名。由于我们系统的,有中文视图,所以有中文。 四、点击名后,其内容列,就会在右边列出现。 与此同时,右边的中部的,条件语句,名部分,也会出现该。 另外,在这里,也有这个名,按显示,就会显示这内的内容,这样设置是为不让当大数据量的出现时,会令软件卡死。 五、在没有条件录入的情况下,可以通按“全查看”生成SQL语句, 再按“执行语句”键,下面的主就出来了。还可以按后面的,“导出XLS”键,导出到XLS。 六,条件查询。 我们要查询 00061号的病人, 1、 首先,在主中选择“门诊病人就诊记录”, 再选择列名, 再选择,主名为“门诊病人记录”的 再选择项目, 选择好后,我们要选择后置条件。 然后选择条件,再按“后置条件增加”它就会出现 在后面的文本框中, 然后单击文本框中的内容,就会传送到,“条件语句”的框中,这个条件就准备好了。 最后按“选列条件”键 ,就会生成SQL语句了。 再按“执行语句”按键,报 就出来了!! 再导出, 时间条件的增加 有由于前置条件要会更SQL语句,所以没有办法,所以前置条件为文本,是让会语句的人直接写入语句用的。在这里写入 由于时间及所学知识有限问题。暂时只能做到这个样子,这个软件还有很足之处,敬请谅解。 新版修正了上一版条件输入的错误。 新版增加了: 1,修改的功能(但请慎用)。按:“方便快捷找出数据库里存放用户名和密码的.doc”的方法,就可以很快找到你想要修改的了。 2、 增加可以导入,导出生成的SQL语句。(方便下次调用,生成XLS) 3、
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值