走一走,看一看,各位大哥,小弟有重要问题请教,请各位大哥帮忙

时间:2021-11-14 04:42:06
我想点新增时同时新增主表,从表数据,主表用DB控件,从表用DBGrid;
把主表和从表的ADO都LockType 为ltBatchOptimistic;从表的sql语句是这样写的,SELECT *
FROM dbo.T3 where a1=:a2;a1为从表中主表ID,
然后把从表的ADO的datasource为主表的datasource 
在新增按钮时写的,主从表的ADO分别APPEND 
然后在保存按钮时写主从表的ADO的UpdateBatch  ,
主表记录有保存进去,但从表记录没有保存进去啊。
请有经验的大哥发表一个意见,多谢了.....

27 个解决方案

#1


我一般绕开数据感知,用非感知控件显示数据,自己通过SQL完成数据库操作。

#2


在主表的afterPost事件中处理从表的新增

#3


不过一般是先建立主表数据,再建立从表数据
逻辑上清晰一些,而且也好处理一些

#4


ADOQuery1为主表的,ADOQuery2为从表的,
这是点保存按钮的事件:
ADOQuery1.UpdateBatch;
这个是在ADOQuery1.AfterPost(DataSet: TDataSet);事件写的。
 ADOQuery2.FieldByName('T3').AsInteger :=ADOQuery1.FieldByName('a').AsInteger;
    ADOQuery2.UpdateBatch();
其中a为主表ID值,t3为从表中的主表ID.但这时ADOQuery1.FieldByName('a').AsInteger值为空啊。

#5


两个表分开更新。

#6


to yf110() 
能详细说一下吗???多谢了。

#7


两个表分开更新。

#8


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了。

#9


你可以用触发器啊,也可以用sql语句来添~!

#10


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了。

#11


建议使用触发器

#12


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#13


写2次插入语句不行吗?

#14


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#15


建议不要使用关联,用SQL语句完成操作,为保证数据一致性,使用事务控制.

#16


Heyongfeng(小何) 
能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#17


use transaction   

ADOConnection.BeginTrans;   
----------------------
your code 
----------------------
ADOQuery1.UpdateBatch;

ADOConnection.CommitTrans;   


#18


TO    nojave(我一定要成为ITer) 
那主从表新是分两次新增,还是用一个新增按钮就可以了。

#19


ADOConnection1.BeginTrans;
  try
      s:='insert into detail(zj,bh,mc,clz,mbz,pcz) values(:zj,:bh,:mc,:clz,:mbz,:pcz)';    //从表
      with inst_qry do begin
        close;
        sql.Clear;
        sql.Add(s);
        for i:=2 to dt_stg.rowcount-1 do
        begin
          for j:=1 to 5 do t[j]:=dt_stg.cells[j-1,i];     //stringgrid为录入的从表记录
          close;
          parameters.ParamByName('zj').Value:=trim(zj_edt.Text);   //主键
          parameters.ParamByName('bh').Value:=t[1];                 //序号
          parameters.ParamByName('mc').Value:=t[2];
          parameters.ParamByName('clz').Value:=t[3];
          parameters.ParamByName('mbz').Value:=t[4];
          parameters.ParamByName('pcz').Value:=t[5];
          execsql;
        end;
      end;

      s:='insert into master(zj,rq,memo,czydm) values(:zj,:rq,:memo,:czydm)';      //主表
      with inst_qry do begin
        close;
        sql.Clear;
        sql.Add(s);
        parameters.ParamByName('zj').Value:=trim(zj_edt.Text);     //主键
        parameters.ParamByName('rq').Value:=rq_dtp.date;
        parameters.ParamByName('memo').Value:=trim(memo_edt.Text);
        parameters.ParamByName('czydm').Value:=czydm;
        execsql;
      end;

    ADOConnection1.CommitTrans;
    showmessage('保存成功!');
  except
    ADOConnection1.RollbackTrans;
    showmessage('保存出错!');
  end;

这里没有使用关联,没有用dbgrid录入记录

#20


那如果用dbgrid录入记录怎么处理啊??使关联那种。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#21


不用那麼復雜,設置以下屬性即可:
增加一個datasource1,其dataset屬性指向主表數據集,
從表數據集的  datasource :=  datasource1,
設置從表數據集的 indexfields ,設置從表數據集的masterfields為主表數據集的某個字段,要與indexfields一致。

主.open; 
從.open;

#22


to  truexf(fey) ( )
 能說詳細一點嗎???。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#23


主从表的操作最好还要用到事务吧,要不操作过程中产生异常,那表里的数据就好看了~~

#24


写触发器

#25


这主要是因为你使用了DataSource数据控件,它要求数据集必须是连通的才可以执行,要保存主从表有两种解决方法:1、用两个Adoquery,一个执行主表,与DataSource关联;另一个对从表执行SQL语句。  2、两个表分开执行,先保存主表,然后释放DataSource字段,在Post成功后,对从表执行SQL语句,然后再关联上主表,重新对主表连接上DataSource,至此OK!
建议使用第一种,方法简便点。
第二种属于全动态设计的,可以少用一个Query,只是设计时麻烦些。

#26


TO zdlou() 
你說的第一種方法是自己寫代碼控制那種嗎?還是怎麼???能說詳細一點嗎???。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#27


用事务提交.
AdoDataSet的属性 Locktype 为 ltBatchOptimistic
....
....{LZ自己的代码包括插入等}
....
ADODataSet1.post;

....
....
....
ADODataSet2.Post;

ADOConnection1.BeginTrans;
try
  ADODataset1.UpdateBatch;
  ADODataset2.UpdateBatch;
  ADOConnection1.CommitTrans;
  showmessage('保存成功!');
except
  ADOConnection1.RollbackTrans;
  showmessage('保存出错!');
end;

#1


我一般绕开数据感知,用非感知控件显示数据,自己通过SQL完成数据库操作。

#2


在主表的afterPost事件中处理从表的新增

#3


不过一般是先建立主表数据,再建立从表数据
逻辑上清晰一些,而且也好处理一些

#4


ADOQuery1为主表的,ADOQuery2为从表的,
这是点保存按钮的事件:
ADOQuery1.UpdateBatch;
这个是在ADOQuery1.AfterPost(DataSet: TDataSet);事件写的。
 ADOQuery2.FieldByName('T3').AsInteger :=ADOQuery1.FieldByName('a').AsInteger;
    ADOQuery2.UpdateBatch();
其中a为主表ID值,t3为从表中的主表ID.但这时ADOQuery1.FieldByName('a').AsInteger值为空啊。

#5


两个表分开更新。

#6


to yf110() 
能详细说一下吗???多谢了。

#7


两个表分开更新。

#8


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了。

#9


你可以用触发器啊,也可以用sql语句来添~!

#10


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了。

#11


建议使用触发器

#12


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#13


写2次插入语句不行吗?

#14


各位大哥,能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#15


建议不要使用关联,用SQL语句完成操作,为保证数据一致性,使用事务控制.

#16


Heyongfeng(小何) 
能详细说一下吗???有没有QQ,我的qq是310076689,多谢了

#17


use transaction   

ADOConnection.BeginTrans;   
----------------------
your code 
----------------------
ADOQuery1.UpdateBatch;

ADOConnection.CommitTrans;   


#18


TO    nojave(我一定要成为ITer) 
那主从表新是分两次新增,还是用一个新增按钮就可以了。

#19


ADOConnection1.BeginTrans;
  try
      s:='insert into detail(zj,bh,mc,clz,mbz,pcz) values(:zj,:bh,:mc,:clz,:mbz,:pcz)';    //从表
      with inst_qry do begin
        close;
        sql.Clear;
        sql.Add(s);
        for i:=2 to dt_stg.rowcount-1 do
        begin
          for j:=1 to 5 do t[j]:=dt_stg.cells[j-1,i];     //stringgrid为录入的从表记录
          close;
          parameters.ParamByName('zj').Value:=trim(zj_edt.Text);   //主键
          parameters.ParamByName('bh').Value:=t[1];                 //序号
          parameters.ParamByName('mc').Value:=t[2];
          parameters.ParamByName('clz').Value:=t[3];
          parameters.ParamByName('mbz').Value:=t[4];
          parameters.ParamByName('pcz').Value:=t[5];
          execsql;
        end;
      end;

      s:='insert into master(zj,rq,memo,czydm) values(:zj,:rq,:memo,:czydm)';      //主表
      with inst_qry do begin
        close;
        sql.Clear;
        sql.Add(s);
        parameters.ParamByName('zj').Value:=trim(zj_edt.Text);     //主键
        parameters.ParamByName('rq').Value:=rq_dtp.date;
        parameters.ParamByName('memo').Value:=trim(memo_edt.Text);
        parameters.ParamByName('czydm').Value:=czydm;
        execsql;
      end;

    ADOConnection1.CommitTrans;
    showmessage('保存成功!');
  except
    ADOConnection1.RollbackTrans;
    showmessage('保存出错!');
  end;

这里没有使用关联,没有用dbgrid录入记录

#20


那如果用dbgrid录入记录怎么处理啊??使关联那种。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#21


不用那麼復雜,設置以下屬性即可:
增加一個datasource1,其dataset屬性指向主表數據集,
從表數據集的  datasource :=  datasource1,
設置從表數據集的 indexfields ,設置從表數據集的masterfields為主表數據集的某個字段,要與indexfields一致。

主.open; 
從.open;

#22


to  truexf(fey) ( )
 能說詳細一點嗎???。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#23


主从表的操作最好还要用到事务吧,要不操作过程中产生异常,那表里的数据就好看了~~

#24


写触发器

#25


这主要是因为你使用了DataSource数据控件,它要求数据集必须是连通的才可以执行,要保存主从表有两种解决方法:1、用两个Adoquery,一个执行主表,与DataSource关联;另一个对从表执行SQL语句。  2、两个表分开执行,先保存主表,然后释放DataSource字段,在Post成功后,对从表执行SQL语句,然后再关联上主表,重新对主表连接上DataSource,至此OK!
建议使用第一种,方法简便点。
第二种属于全动态设计的,可以少用一个Query,只是设计时麻烦些。

#26


TO zdlou() 
你說的第一種方法是自己寫代碼控制那種嗎?還是怎麼???能說詳細一點嗎???。。有没有QQ,想和你交流一下。我的qq是310076689,多谢了

#27


用事务提交.
AdoDataSet的属性 Locktype 为 ltBatchOptimistic
....
....{LZ自己的代码包括插入等}
....
ADODataSet1.post;

....
....
....
ADODataSet2.Post;

ADOConnection1.BeginTrans;
try
  ADODataset1.UpdateBatch;
  ADODataset2.UpdateBatch;
  ADOConnection1.CommitTrans;
  showmessage('保存成功!');
except
  ADOConnection1.RollbackTrans;
  showmessage('保存出错!');
end;