在一个多用户环境中,大概20+个用户,随时可能读取数据,每一个用户都应该读取到其他用户未访问过的数据,如果某个记录已经被其他用户修改过(有修改位的标志)或正在被某个用户访问,那么其他的用户在读取下一条数据的时候,就不应该得到这些数据,应该继续向下寻找没有被修改过并且不是正在被其他用户访问的数据。要实现以上的功能,有什么好办法吗,最好具体一点,后台数据库是 sql server ,前台是delphi谢谢各位了

解决方案 »

  1.   

    好方法没有,有坏方法一个,不知管用不:
    给表加一个标识字段,如果用户访问了某些数据,给这些数据的标识字段设一个已读取标识就好了。比如加一个"HasRead" 字段,为int型,默认为0,标识未读取,如读取后,设为1,读取时,SQL中加入 where HasRead > 0 条件,应该可以了。
      

  2.   

    同意樓上的建議。
    因爲要對訪問的記錄作標記,最好在表中增加一個INT型標識字段,初始爲0,每修改一次+1。
    “易飛ERP”中每一個表中都有這樣的標識字段。
      

  3.   

    看是什么数据库,如果是oracle类,本身就具有你要求的
      

  4.   

    加入一个表示字段的方法我已经用过了,但是在多用户环境下测试的时候,发现很快就出现了读取到重复纪录的情况。
    顺便说一下环境:
           操作系统 :win2000
           数据库   : sql server2000
           前台     :delphi 6
           需要处理的记录容量大概在 10W左右,
           网络环境 :100M交换环境
    我加了一个标识字段,一位字符的,默认值为0,如果用户正在读取这条记录,就把这条记录的标识字段设置为1,其他用户读取数据的时候就读取标识字段为0的。但是有两个用户同时读取到同一条记录的情况,这是万万不能出现的情况。郁闷中。希望大家帮忙想想有什么好办法吗?其实这个问题也是一个比较典型的多用户问题,希望我们能够共同努力想到一个好的解决办法,谢谢了。
      

  5.   

    sql本身没这样的机制,这个问题我n年前就遇到过了。当时也只能用1楼的方法去做。我们那时要求不高,勉强达到要求,象楼主说的万万不能多个人读取到同1条记录,真的没好办法。期待高人出现!
      

  6.   

    sqlsever本身有一种数据类型可以控制这种情况的
    一时忘了,给你找找~~
      

  7.   

    建议用事务处理,保证当前用户读取记录被锁定,其他用户无法读取,具体的实现方法是:
    adoconnection1.begintrans;
    try
      adoconnection1.execute('UpdateSQLsting');//更改读取标识
      adoquery1.recordset:=adoconnection1.execute('SearchSQLstring');//打开读取
      adoconnection1.committrans;
    except
      adoconnetion1.rollbacktrans;
    end;
      

  8.   

    使用事务并不好使,当一个事务挂起时,整个表都可能死锁直到那个事务commit 或rollback
    其他事务都得等待~~
      

  9.   

    var
    sqlstr,mytel,mydate:string;
    begin
     sqlstr:='select top 1* from table1 where his=0 and reader=0';//两个条件都符合时查询记录
     adoquery1.Recordset:=adoconnection1.Execute(sqlstr);
     mydate:=datetimetostr(now);//访问时间
     mytel:=adoquery1.FieldByName('tel').AsString;
     if mytel='' then//表示记录为空时中断本次操作
        abort;
       adoconnection1.BeginTrans;
     try
       adoconnection1.Execute(sqlstr);
       sqlstr:='update table1 set reader=1 where tel='''+mytel+'''';//置有人访问状态
       adoconnection1.execute(sqlstr);
       //这里可以插入其他操作
       //操作完毕
       //置访问过的时间和状态
       sqlstr:='update table1 set isdate='''+mydate+''',his=''1'',reader=''0'' where tel='''+mytel+'''';
       adoconnection1.Execute(sqlstr);
       adoconnection1.CommitTrans;
     except
       adoconnection1.RollbackTrans;
     end;
    end;
    //以上的his字段实际上可以不要,那么his=0就可以用isnull(isdate,0)=0替代
    //另外,isdate是SQL 里的一个函数,如果你用这个做为字段名会有错误隐患,建议更改
    //代码本身无错误,但没有做大量数据测试
    //建议将代码做成一个过程,放在客户的触发事件
      

  10.   

    首先要求相关字段有索引存在.
    每条记录都有一个唯一性标记,先SELECT 无标记的,记下标记字段
    UPDATE你的读取标记字段
    读取记下的标记字段对应的数据
      

  11.   

    SQLServer2000可以实现的,用行锁,你看看书