100分 检索数据是否在库中重复!(100)

  • 主题发起人 主题发起人 host71
  • 开始时间 开始时间
H

host71

Unregistered / Unconfirmed
GUEST, unregistred user!
1.最好用dbedit作为输入控件。如有可能配合locate检索重复。没用过感知控件和locate的同志不要回答,相关帖http://www.delphibbs.com/delphibbs/dispq.asp?lid=39483952.快速检索数据库中是否有重复数据,建议不采取数据库建主键方式。3.在输入时触发(onexit)或者保存的时候触发(beforepost)都可以,同时校验最好。4.代码要少,要精,要让人有耳目一新的感觉,尽量不要使用query(select)。5.如有更好的建议可以单独加分。
 
Locate只对对本地缓存中的数据进行检索,LZ确定自己的程序不可能2个人同时使用你的软件进行数据增加操作?当前DataSet保存前,如果调用了Locate函数,会导致当前DataSet自动保存,这一点LZ应该知道吧?除非你另外用一个DataSet来处理Locate功能,但问题如同上面说的,确定自己的程序不可能2个人同时使用你的软件进行数据增加操作?如果数据库内有30万条记录,使用Locate,会把所有数据全部查询到当前机器内存,然后再检索,效率非常底下的。
 
感谢znxia的回复,是我最近一段时间收到的最好的回答,呵呵。我在盒子,CSDN和大富翁上都发帖了,只有仁兄对这个东西这么透彻!我在beforepost里重新实例化了一个dataset来locate。例如:原来是adotable1beforepost内:var atbl:Tadotable;begin atbl:=Tadotable.create(); atbl.connection:=adotble1.connection; atbl.tablename:=adotable1.tablename; atbl.active:=true; if atbl.locate('vipid','0198',[]) then begin showmessage('重复'); adotable1.cancle; end;end;(示例代码)自己想出来的,这段东西实际用了下感觉从原理上还可以,但是自认为不完美所以没有最终使用,在几个群里也和朋友们聊这个事情,暂时也还没有定论。不知道znxia兄有没有什么高见,一般你的程序中都用什么检索!本帖旨在探索一个经济实用的检索重复的途径,因为这个检索是所有数据库开发的用户都会遇到的,所以一来希望大家都拿出来分享,二来找到一个最佳的解决办法!方便的加QQ:4465253,谢谢。
 
呵呵,刚才看到消息后,还在找你的帖子呢。对于要求唯一的,我一般都在数据库上加一个约束,确保即使我程序写错了,数据库中也不会出现重复的数据。beforepost内:var atbl:Tadoquery;begin atbl:=Tadoquery.create(); atbl.connection:=adotble1.connection; atbl.sql.text:=format('Select count(*) from %s where vipid=''%s'' and 主键<>%d ',[adotable1.tablename, '0198', adotable1主键字段值]); //需要考虑修改的时候的情况,所以把主键加上来,表示不判断当前记录。 atbl.active:=true; if atbl.fields[0].asinteger>0 then begin showmessage('重复'); Abort; // adotable1.cancle;用abort可以阻止程序继续运行,但状态仍然是编辑,你cancel会把别人辛苦3分钟录入的数据丢失的。 end;end;(示例代码)
 
忘了释放控件了,
 
abort,在写完时候想到了,考虑到是示例所以没改,因为并不是主要部分。我开始考虑用locate主要是感觉到是个非常有用的过程,简洁实用。没想到就是你在一楼说的问题所有的数据感知控件(dbedit,rzdbedit,dxdbedit,dbgrid,cxgrid实测)在失去焦点时都会把对应数据更新到dataset中去,所以locate实现不了检索的功能了。当时认为1.dbedit类控件可以不去自动跟新dataset或者可以设置为不去跟新。2.考虑只locate原来的不locate缓冲区数据,所以衍生出上边2楼的代码。所以从dbedit和locate下手搞了一周没有突破,再看了 CSDN 上一个叫做“关于dataset的研究”的帖子,似懂非懂的放弃了dbedit+locate的想法。感觉dbedit等数据感知控件不为人们所识所用真是挺遗憾的!所以还是希望大家多用用数据感知类控件除了dbgrid。[red]能得到znxia帮助感到十分高兴,谢谢!看看其他兄弟们在:数据感知控件、locate、检索数据重复。方面还有没有什么高见。如果没有尽快结贴了。不过还是希望大家踊跃留言,一来大家互相拓展思路,另一方面是个交流的机会。也给我们这些菜鸟们一个学习的机会,给大家留下一个经典的数据检索重复的算法![/red]
 
可能我已经到一个漩涡里了,总认为delphi这么功能强大的编译器,应该有一个判断重复的函数或者过程可供使用,没想到是真没有。令继续请教znxia,如果是多人使用如何检索重复,是不是只能考虑加数据库表的主键、外键或者约束了?程序上控制只能依靠锁表操作,但是这样会降低多客户端的工作效率。不知大师用什么方法。再有3楼代码是你改造我的,你在写库的时候是怎么检索重复的呀,能不能也给示例下,谢谢。呵呵。
 
我来说说我的看法1、在网络环境下,像2楼说的,要检索数据是否重复,不是只用LOCATE就能解决的,就算你在打开的时刻下载的所有的主键信息,也并不能保证其他用户已经录入了但还没提交的数据中,不含有重复数据。2、有关效率问题,其实用LOCATE的方式,(这里不考虑数据是否会被提交及多少用户的问题),除了先要下载全部数据(当然可以设置成只下载主字段的全部数据),同样LOCATE本身也需要时间,当数据量达到一定量后,相比一下,采用SELECT COUNT(keyField) From table where keyfield= value的方式,其速度与记录数的比率,远远要比LOCATE来得低,所以不要想当然的就认为SELECT语句不好。3、如何采用数据感知元件实时判断是否重复的问题,其实BEOFREPOST并不好,除非你表只有一个字段,否则还是要等所有字段都输入了,提交时才会得知是否重复,所以较好的方式是在 Field.OnChange的时候,进行处理,此事件发生于数据输入,回车确认时,也就是元件即将丢失焦点时。4、还是回到多用户的环境时的问题,假设A用户在输入了数据,查询后得知并不存在,继续在录入另外的数据,但此时B用户也正好查询后不存在,先于A用户提交的数据,(这种情况在用有一定规律的类似流水号的号码作为主键时发生的概率最大,当然用随机类型的无序主键如类似GUID之类的,就偏小),此时等B用户再提交数据时,还是会出错。所以从程序的安全性考虑,你还是得做异常处理。这样就又回到了原点,既然从程序安全性考虑,我要用一个异常处理,防止重复主键的情况发生,那又何必采取一堆浪费效率的语句来查询主键是否存在呢?还不如直接设定为主键或者UNIQUET约束,然后捕获异常来处理好了。以上是个人的一些愚见,见笑。
 
1>我在处理是否重复的时候,三个约束,A:数据库约束;B:DBEdit中离开焦点时做检查; C:BeforePost事件中再次检查(和B中调用同一个检查函数)2>我始终看好Select,而不是Locate,呵呵,我们意见不一致而已;
 
说说我的愚见我一般是数据库设置主键,然后程序对对应的字段在录入完成时做一个判定,如果除了主键外其他字段没问题,符合要求就POST提交,在做一个try来捕获异常,一般情况下,程序验证了其他字段没有问题时,提交出错就是因为主键重复造成的(当然特殊情况除外),再告知用户主键重复。个人感觉程序写多了后,虽然写程序要求要对自己的代码和程序安全性都做严密的推敲,但是有时候不能对每一点都能做到完美,只能根据实际的工作环境和可以容忍的限度内做一些调整,并不可能任何都做到百分百的完美。就好比做通讯、网络的程序,上面的异常太多,不可能每一种异常都一一处理,只能是根据自己的需要去处理某一部分而已。都是个人看法。别见笑
 
levi兄,谢谢回帖。[red]大师们有没有封装了的检索重复的函数或者过程,拿出来秀一下呀![/red]
 
请问是否可以把chrome嵌入到自己的应用程序中?开发Web浏览小工具,要求如下:1、内嵌Google浏览器。2、运行程序可以读取配置文件中设置的URL,并在内嵌的Google浏览器中打开。3、内嵌Google浏览器要求不允许显示浏览器地址栏等信息,只显示页面。能完成此工具的可以走外包形式。联系人: 林先生电话: 13683611366
 
多人接受答案了。
 
后退
顶部