表t1: create table t1(spbh char(10) not null,spmc char(10) not null,lbbh char(10) not null)表t2:create table t2(rkdh char(10),spbh(10),rksl float,rkdj money)建立视图:
create view vw_rkd
as
select t2.rkdh,t2.spbh,t1.spmc,t2.rksl,t2.rkdj,rksl*rkdj as rkje
from t2 inner join t1 on t2.spbh=t1.spbh前台使用一个dbgrid,一个adoquery来连接这个视图.
我在Dbgrid中录入数据后,不能更新,显示:
lbbh 不能为空.如何解决这样的多表视图更新问题?
create view vw_rkd
as
select t2.rkdh,t2.spbh,t1.spmc,t2.rksl,t2.rkdj,rksl*rkdj as rkje
from t2 inner join t1 on t2.spbh=t1.spbh前台使用一个dbgrid,一个adoquery来连接这个视图.
我在Dbgrid中录入数据后,不能更新,显示:
lbbh 不能为空.如何解决这样的多表视图更新问题?
你建立表时都不允许输入为空值,现在想插入存储空值?,不行.
还是输入lbbh值吧.
要不就把lbbh字段允许输入空值.
但是在Delphi中录入后保存就显示 lbbh不能插入空值.二个环境都没有录入LBBH这个字段.
后来为adoquery设了一个属性,
Recordset.Properties.Item['Unique Table'].Value:='t2';
还是不行.
我在Dbgrid中录入数据后,不能更新,显示:
lbbh 不能为空. 如何解决这样的多表视图更新问题? 你更新表t2是用哪个adoquery连接了?不会也是用同一个adoquery连接视图的吧?如果是就错了.
视图是当你更新基表t2时,再执行一次查询时,视图也就会是最新数据了.
这是企业级开发的技术资料!!!!!!!!将TAdoQuery或TQuery赋与TDataSetProvider的DataSet属性,再将DataSetProvider.Data赋与TClientDataSet.Data,数据改变后将TClientDataSet.Delta传给DataSetProvider的ApplyUpdates方法。
如果是视图,遍历TClientDataSet的所有字段,将非更新表的字段FieldByName( 'lbbh ').ProviderFlags := []; ~~再将TClientDataSet.Delta传给DataSetProvider的ApplyUpdates
这个和视图无关,和ADO有关,解决方案有2种
1、不通过视图更新,直接通过SQL更新表
2、通过原生SAO设置MASTER表,也就是设置到底更新那个表
看来很多人对这些问题有疑问,简单总结一下各种解决方案1、不使用视图,直接使用TADOQuery,其SQL属性就是上面的代码,但是需要设置LockType属性,然后手动后台更新
2、不使用视图,直接使用TADOQuery,其SQL属性只是简单的代码,关联表采用查询字段,也就是无论如何也不会更新另外的关联表
3、使用视图,方法同一
4、不使用视图,直接使用TADOQuery,设置MASTER表,也就是ADO.Properties.Item['Unique Table'].Value设置为主表,然后再进行操作但是无论那种方法,你的问题都可能存在,因为这个已经和ADO关系不大,是你的数据库设置了不必要的非空值。
:
procedure TFrmPublicdata_child.dsp_childBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
var Applied: Boolean);
var
aq:TAdoquery;
sqlS:String;
procedure SetParams(aQuery:TAdoquery);
var
i:integer;
aParameter:TParameter;
begin
for i := 0 to DeltaDS.fieldcount - 1 do
begin
aParameter:=aQuery.Parameters.FindParam(DeltaDS.Fields[i].FieldName);
if aParameter<>nil then
aParameter.Value:=DeltaDS.Fields[i].Value;
end;
end;
begin
inherited;
aq:=tadoquery.Create(nil);
aq.Connection:=aq_child.Connection; try
Case UpdateKind of
ukInsert: aq.sql.text:=child_sql_insert;//child_sql_insert:='insert into t_sprk_m ......
ukModify: aq.sql.text:=child_sql_Modify ;
ukDelete: aq.sql.text:=child_sql_delete;
End;
setparams(Aq);
aq.Execsql;
finally
freeandnil(Aq);
end; Applied := True;
end;3\和数据库中的非空值无关,因为数据表中的这个字段必须是非空值的.我不是改变这个数据表,而只是要显示这个数据表的一部分.其它各种解决方案都无法实现我的需求.这个其实是部分变相地采用了三层技术,来实现C/S架构.哈哈.
cds_child.post;
5\与总表一起保存部分:(真实地提交到数据库中)
cds_Child.applyupdate(-1);这样子就成功了.