用  select  fd1,fd2,fd3  from  table1  where  fd1='xxx'  这样的SQL语句得到的记录集有多条记录(fd1不是表的关键字)。把fd2,fd3绑到Form上的DBEdit控件上,想通过DBEdit控件编辑这记录集中多条记录的fd2,fd3的值。原以为通过DBEdit控件修改字段值时,TQuery控件会产生  update  table1  set  fd2='aaa',fd3='bbb'  where  fd1='xxx'  这样的SQL语句(注意:where  fd1='xxx'),没想到自动产生的SQL语句竟然包括表中的主键字段,而主键字段不没有出现在原来的select语句中。 Database: MS SQL Server 2000 
 
问:有什么办法让TQuery控件按  where  fd1='xxx'  条件更新?

解决方案 »

  1.   

    自己编写代码控制,比如在dbedit的失去焦点事件里面写query的更新代码(前提是dbedit里面的内容改了,否则你的代码没有效果,正好也可以验证你的代码是否正确?
      

  2.   

    最好不要用DBEDIT你可以用EDIT就可以了
      

  3.   

    当你更新数据的时候sql server会自动生成一个更新数据的事物,里面是按照主键来更新的,而且本地的数据也是按照主键提取的,如果你强行要按照你的要求写更新语句,可以写在onupdate事件里面
      

  4.   

    我也 觉得用Tedit比 TDbedit 好!
    这样你可以比较容易的实现
      

  5.   

    TQuery有个属性叫UpdateMode,可取的值为:
    upWhereAll,upWhereChanged,upWhereKeyOnly。它们控制了TQuery生成Update的方式。
    你打开SQLServer的事件探查器,把TQuery分别设置这三种模式运行,即可看到它们生成代码的不同之处了。
    如果要自己控制更新语句,可以加入一个TUpdateSQL组件,然后将TQuery的UpdateObject设置为这个组件。再分别为TUPdateSql设置插入、更新、删除的SQL语句即可(更详细的说明请参考TUpdateSql的帮助)。
      

  6.   

    谢各位!1. 用TEdit比较麻烦,要对输入的数据进行各种检验,否则容易出错,我轻易不用。
    2. 就是因为不想自己写update语句,才想看看有什么“捷径”
    3. UpdateMode的三种模式都试过,全都会自动加上主键。
    4. yjs_lh(长风浪子)说的TUpdateSQL与TQuery结合的办法以前没有试过,我准备好好试试。
      

  7.   

    TUpdateSQL与TQuery结合的办法比較靈活﹐不易出錯。建議使用
      

  8.   

    从来没用过DBEDIT,一直坚持用EDIT,
      

  9.   

    试了一下TUpdateSQL,有问题请教:
    帮助上说TUpdateSQL用于read-only的数据集的更新。可是这样的数据集不能被编辑,难道只能用非绑定数据源的类似TEdit的控件?否则,TUpdateSQL语句怎么得到新的字段值?请指点。
      

  10.   

    你的要求不能成功,一般默认的设置是键值字段加所有修改后的键组成where后的条件
    这样可以防止你修改多条,假如你不需要修改多条,完全可以只使用键值来组成where条件
    代码如下:
    var
      pty : Property_;
      pties : Properties;
      pcount : integer;
    begin
      pties := ADOQuery.Recordset.Properties;
      for pcount := 0 to pties.Count -1 do
      begin
        pty := pties.Item[pcount];
        if pty.Name = 'Update Criteria' then
        begin
          pty.Value := 0;//只使用键值字段作为where条件1,使用所有字段2,默认设定3,略
        end;
      end;
    end;
      

  11.   

    在所有的UpdateCriteria属性的模式中都必须包括键值字段
      

  12.   

    记得ClientDataset的子段有UpdateFlags属性,你可以利用一下
    ClientDataset.fieldbyname('emp_no').updateflags:=[Pflnupdate]
    //这样子段就不出现在update语句中。
    怎样用Clientdatset代替Query你应该会吧
      

  13.   

    另外自己写SQL语句,我觉得实在没有什么烦琐之处,有时候控件没有的功能,你不可能期望用控件除非你自己改写控件。个人观点供参考。
      

  14.   

    不好意思没看清你用的是TQuery
    yjs_lh(长风浪子) 的做法可能也是必须包含键值字段的
      

  15.   

    感谢以上各位朋友的参与。1. 数据库是我设计的,出于尽可能简化的目的,我把2个表合并成一个表,不符合三范式,但减少了表的数量,也简化了以后的查询。但这样就不能使用主键字段来区别记录。2. 尽管有其他的实现办法,我还是想用TDBEdit这样的控件简单地实现数据编辑的功能。3. 我试用了TUpdateSQL控件,其中给出了我希望的Update-SQL语句,并且也执行了。通过MS SQL Server 的事件探查器可以看到所希望的Update-SQL语句执行完毕,查询表数据也能看到多条记录的数据也同时发生了变化。4. 现存问题1:TUpdateSQL控件用于更新只读的TDataSet(如TQuery),可如果TQuery的数据集是只读的,其绑定的TDBEdit控件也就不能编辑数据。不明白TUpdateSQL用在什么场合,矛盾!5. 现存问题2:如果TQuery的查询语句适当(不使用多表、Distinct等),可以将其RequestLive设为true. 则在绑定TUpdateSQL控件后好像或发生2次更新,TUpdateSQL一次,TQuery自己还有一次,而且TQuery的更新会出错。无法解决!
      

  16.   

    你这样的要求比较特殊,实现起来可能有难度。我的理解中,TQuery是不可能这么智能,自动产生update的SQL的。即使是要有可更新的查询,也是通过TUpdateSQL或其他手段实现的。在TUpdateSQL这样的环境中,主键的信息是必须出现的,否则它无法定位记录。象你说的这样的情况,还是手工编写SQL更方便,有这么多时间讨论这个问题,问题已经可以通过别的方法解决了。你说的另两个问题:
    现存问题1:TUpdateSQL控件用于更新只读的TDataSet(如TQuery),可如果TQuery的数据集是只读的,其绑定的TDBEdit控件也就不能编辑数据。不明白TUpdateSQL用在什么场合,矛盾!::TUpdateSQL就是用在更新TQuery的情况中。只要UpdateSQL书写得当,一般没有什么不可更新的TQuery。现存问题2:如果TQuery的查询语句适当(不使用多表、Distinct等),可以将其RequestLive设为true. 则在绑定TUpdateSQL控件后好像或发生2次更新,TUpdateSQL一次,TQuery自己还有一次,而且TQuery的更新会出错。无法解决!
    ::在这样的情况下,要么只用TUpdateSQL,要么只用RequestLive=true。我推荐前者。
      

  17.   

    推荐使用TUpdateSQL——设置好sql语句即可。
      

  18.   

    Acquarius(二当家)没明白我的意思!TQuery的数据集既然是只读的,数据集的数据通过什么发生变化?!!!你别告诉我是通过TUpdateSQL,因为它用于把TQuery的变化对应到数据库中的。
      

  19.   

    现在问题比较清楚了:TUpdateSQL的Update语句不能修改多个纪录,如果修改多个纪录就会出错“Update failed”。我本想用错误捕捉来忽略这个错误(因为它已经修改了多个纪录),却捕捉不到错误。如何解决?
      

  20.   

    TQuery的数据集一般而言是只读的。数据集的数据可以有很多种方法去修改。通过TUpdateSQL只是其中的一个方法。TQuery本身并不包含数据,它是从更基本的地方得到数据,例如一个表。你修改TQuery的数据,间接的就修改了Table的数据,反过来也一样。“TUpdateSQL的Update语句不能修改多个纪录,如果修改多个纪录就会出错“Update failed”。”要看你怎么理解,如果你要批量修改数据,那么当然是直接编写update ... set ... where ...更加直接了。我已经说了,UpdateSQL一定要你提供主键信息,那么在一个时候,一定只有一个主键信息,当然也就只能对一个记录修改了。但是,我们可以在不同的时候给予不同的主键信息啊。
      

  21.   

    觉得对数据表的更新操作,最好不要用数据敏感控件来实现,而要自己用SQL语句来实现。
    这样比较好控制,并且易于维护!愚见,仅供参考。