表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 不能为空.如何解决这样的多表视图更新问题?

解决方案 »

  1.   

    这不关视图的问题,lbbh   char(10)   not   null,
    你建立表时都不允许输入为空值,现在想插入存储空值?,不行.
    还是输入lbbh值吧.
    要不就把lbbh字段允许输入空值.
      

  2.   

    我只更新视图的中的表t2,不更新表t1.所以还是于视图有关.我建立视图后尝试在SQLSERVER中录入数据(只录入t2的数据),没有问题,
    但是在Delphi中录入后保存就显示 lbbh不能插入空值.二个环境都没有录入LBBH这个字段.
    后来为adoquery设了一个属性,
    Recordset.Properties.Item['Unique Table'].Value:='t2';
    还是不行.
      

  3.   

    前台使用一个dbgrid,一个adoquery来连接这个视图. 
    我在Dbgrid中录入数据后,不能更新,显示: 
    lbbh   不能为空. 如何解决这样的多表视图更新问题? 你更新表t2是用哪个adoquery连接了?不会也是用同一个adoquery连接视图的吧?如果是就错了.
    视图是当你更新基表t2时,再执行一次查询时,视图也就会是最新数据了.
      

  4.   

    lbbh 中输入数据或允许为空就可以了
      

  5.   

    lbbh 中输入数据或允许为空就可以了
      

  6.   

    lbbh 中输入数据或允许为空就可以了
      

  7.   

    ADOQuery1.FieldByName('lbbh').ProviderFlags := [];
      

  8.   

    在我的开发框架中,可实现视图的多表更新,读出的视图改变后,只要指定视图的更新表就可以保存了!
    这是企业级开发的技术资料!!!!!!!!将TAdoQuery或TQuery赋与TDataSetProvider的DataSet属性,再将DataSetProvider.Data赋与TClientDataSet.Data,数据改变后将TClientDataSet.Delta传给DataSetProvider的ApplyUpdates方法。
    如果是视图,遍历TClientDataSet的所有字段,将非更新表的字段FieldByName( 'lbbh ').ProviderFlags   :=   [];  ~~再将TClientDataSet.Delta传给DataSetProvider的ApplyUpdates
      

  9.   


    这个和视图无关,和ADO有关,解决方案有2种
    1、不通过视图更新,直接通过SQL更新表
    2、通过原生SAO设置MASTER表,也就是设置到底更新那个表
      

  10.   


    看来很多人对这些问题有疑问,简单总结一下各种解决方案1、不使用视图,直接使用TADOQuery,其SQL属性就是上面的代码,但是需要设置LockType属性,然后手动后台更新
    2、不使用视图,直接使用TADOQuery,其SQL属性只是简单的代码,关联表采用查询字段,也就是无论如何也不会更新另外的关联表
    3、使用视图,方法同一
    4、不使用视图,直接使用TADOQuery,设置MASTER表,也就是ADO.Properties.Item['Unique Table'].Value设置为主表,然后再进行操作但是无论那种方法,你的问题都可能存在,因为这个已经和ADO关系不大,是你的数据库设置了不必要的非空值。
      

  11.   

    哈哈.谢谢你们的解答,其实这个问题的确是ADO的问题.我的解决方案在我研究了各种解决方案后,真正实现并且唯一实现我的需求的东西:1\建立一个CLIENTDATASET与TDataSetProvider,一个adoquery与datasource.Datasource-->Clientdataet-->TdatasetProvider-->adoquery2\在TDataSetProvider的onBeforeUpdateRecord过程中写程序,赋需要的SQL语句.如下例
    :
    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架构.哈哈.
      

  12.   

    4\ 保存部分:
       cds_child.post;
    5\与总表一起保存部分:(真实地提交到数据库中)
       cds_Child.applyupdate(-1);这样子就成功了.
      

  13.   

    把lbbh設置为允许为空不就行了