首页 >> 读书频道 >> 电脑 >> RDO 的建立记录集(一)
 
· RDO之Informix
· XBase与VB用法对照
· 数据库的锁定
· 如同XBase的Macr
· 如何将其他资料汇入MDB
· Tandem Unstr
· VB数据库记录查询四法
· Visual Basic
· ADO Update C
· ADO的建立连结
· 在记忆体中的ADO记录集
· 用VB实现全屏幕图形界面
 
· 电视剧《刁蛮公主》下载和
· 美容养颜手册
· 加油金顺剧情分集介绍完整
· 红楼梦:120回全本[清
· 素质教育在美国
· 全唐诗卷四十六
· 韩剧《布拉格恋人》剧情介
· 夜航船[作者:明·张岱]
· 局外人[作者:韩·可爱淘
· 现场流行病学
· 源氏物语[日本:紫式部]
· 武林寓言故事
 
· (出租)中动商场部分及写
· (出租)中动动漫基地&#
· 喜剧学院
· 《善德女王》剧情介绍
· 魔女18号 剧情
· 丑女无敌剧情介绍
· 魔女幼熙剧情介绍
· 龙游天下剧情介绍
· 震撼世界的七日剧情介绍
· 静静的白桦林剧情介绍
· 心情日记—老公今天我想对
· 旗舰剧情介绍
欢迎来到月影社区!如果您觉得这里不错,请推荐给您的朋友们。月影社区:http://wf66.com/

RDO 的建立记录集(一)


查看有无更新版本

关键字:VB 2006-9-18

 

上回谈的是如何建立连结,这SQL与Informix没有什麽不同,但是
再来要谈的是令人十分痛苦的事了,那便是如何产生一个rdoResultSet物件
rdoResultSet相对应於DAO的Recordset物件,产生的方式主要如下:
Private WithEvents cn As rdoConnectionPrivate en As rdoEnvironmentPrivate rs As rdoResultsetPrivate qry As rdoQueryDim sql As String Set en = rdoEnvironments(0)Set cn = New rdoConnectionen.CursorDriver = rdUseServer '见注一connstr = "UID=cww;PWD=jjh5612;Database=cwwpf@eis;" _ + "Driver={OpenLink Generic 32 Bit Driver};" _ + "Host=192.168.0.61;" _ + ";FetchBufferSize=30" _ + ";NoLoginBox=Yes" _ + ";Options=" _ + ";Protocol=TCP/IP" _ + ";ReadOnly=No" _ + ";ServerOptions=" _ + ";ServerType=Informix 7.2"cn.Connect = connstrSet cn = en.OpenConnection("", rdDriverNoPrompt, _ False, connstr) '第三个叁数False表示非ReadOnly..rs.Closecn.Close
如果不想cn 加入en.Connections之中,则改用以下方式
Set en = rdoEnvironments(0)Set cn = New rdoConnectionconnstr = "UID=cww;PWD=jjh5612;Database=cwwpf@eis;" _ + "Driver={OpenLink Generic 32 Bit Driver};" _ + "Host=192.168.0.61;" _ + ";FetchBufferSize=30" _ + ";NoLoginBox=Yes" _ + ";Options=" _ + ";Protocol=TCP/IP" _ + ";ReadOnly=No" _ + ";ServerOptions=" _ + ";ServerType=Informix 7.2"Set cn = New rdoConnectioncn.CursorDriver = rdUseServercn.EstablishConnection rdDriverNoPrompt, Falsesql = "Select * From qppfa"Set rs = cn.OpenResultset(sql, rdOpenForwardOnly, _ rdConcurReadOnly)..rs.Closecn.Close
重点都是在OpenResultset这个方法上,但是如果要做更多的控制,我会在rdoQuery上使用OpenResultset,如下:
Set en = rdoEnvironments(0)Set cn = New rdoConnectioncn.CursorDriver = rdUseServerconnstr = "UID=cww;PWD=jjh5612;Database=cwwpf@eis;" _ + "Driver={OpenLink Generic 32 Bit Driver};" _ + "Host=192.168.0.61;" _ + ";FetchBufferSize=30" _ + ";NoLoginBox=Yes" _ + ";Options=" _ + ";Protocol=TCP/IP" _ + ";ReadOnly=No" _ + ";ServerOptions=" _ + ";ServerType=Informix 7.2"cn.Connect = connstrcn.EstablishConnection rdDriverNoPrompt, Falsesql = "Select * From testtab"Set qry = cn.CreateQuery("MyQuery", sql)qry.RowsetSize = 50 '见注二qry.MaxRows = 200 '见注三 Set rs = qry.OpenResultset(rdOpenKeyset, _ rdConcurRowVer)..rs.Closecn.Close
至於说OpenResultset方法中又提及记录集又分成以下四种:rdOpenForwardOnly 0 (预设值)是固定集 (Fixed Set),不可卷动 (Non-Scrolling)rdOpenKeyset 1 固定集,可卷动的查询记录集的资料指标,存的只是Key,而其 他的资料於需要时可以去读取,因此它可以读到其他人更新过後 的资料,当然,需和RowSetSize做搭配,别人在我们读取到Data 後才更新资料时,我们的Process仍然没有反映最新的资料,此 时下个Move 0指令可以更新至最新的Data。不过看不到其他人新 增到该Result Set的资料 rdOpenDynamic 2 动态集的资料指标,特性和rdOpenKeyset同,唯其他Process加入 该Resultset的资料可以在目前Process中看到。rdOpenStatic 3 是固定集,和rdOpenKeyset不同的是,资料集一建立之後就看不 见其他Process对Resultset的修正。其实,我觉得MS 对於这些东西的说明十分不清楚,而且上面的说明针对的都是rdUseServer的Server端之Cursor,而ODBC端的Cursor没有像上面所说的那样,ODBC端的Cursor因为资料是Copy到Client端,自然也就看不到他人是如何对Resultset成员的修改了;当然了,理论上还是可以得知,不过这要花上代价,那就是每一次读取资料时还得向Server来询问是否有改,那不就失去Client端Cursor的原意了吗?所以我们可以想像,ODBC端的Cursor只有rdOpenForwardOnly与rdOpenStatic这两种。这样就结束了吗?还没有!以上是MS SQL SERVER6.5的特性,而Informix呢?InforMixServer端的Cursor只有rdOpenForwardOnly与rdOpenKeyset两种(注意,不是rdOpenStatic)这和Informix Server有关,然而我们在Informix为後端的Server中使用rdOpenStatic/rdOpenDynamic时,也不会有误,只是行为和rdOpenKeyset相同。而Informix为後端,但我们使用rdUseOdbc之Client端Cursor呢,此时只有rdOpenForwardonly与rdOpenStatic(注意,不是rdOpenKetset喔),这个原因是来自於ODBC Cursor的特性。而不管是SQL SERVER或Informix为後端,rdUseNone的方式就没有太多的选择,一律只能使用rdOpenForwardonly的Cursor型态,这不必多说,应是很自然的事吧。透过上面的说明,何时用Client端的Cursor何时用Server端的Cursor应比较有念了吧。注一:CursorDriver 有以下数种方式rdUseIfNeeded 0 ODBC 驱动程序 将选取适当的资料指标样式。可能的话,使用 伺服端资料指标。rdUseOdbc 1 将使用ODBC 资料指标程序库(ODBC Cursor Library)。rdUseServer 2 使用伺服端资料指标。rdUseClientBatch 3 RDO 将使用乐观批次资料指标程序库 rdUseNone 4 记录集(Result Set)不以资料指标型态传回。而这里想讨论的是rdUseOdbc rdUseServer rdUseNone,而rdUseClientBatch不多做讨论rdUseOdbc 在Client端建立Cursor来管理Cursor的移动,因为是在Client端,所以实作 上是在Client端Copy一份ResultSet,不同的Client端各自有其一份资料; 假设有A,B两个Client端要求了相同的资料,如:都是下Select * from testtab 之SQL指令,假设一共有740笔资料,那麽,A, B各自保有740笔资料,如果 对这些资料作更动,A看不见B,B也看不见A(这合理嘛,因为各自有其资料 的Copy )。然而这740笔资料是在什麽时候传到Client端呢?并不是OpenResultSet 时便立即全部传过来,而是一开始只传部份的资料过来,而Cursor指到後面 的资料时,才会将之再传过来。所以,如果我们使用MoveLast方法时,会看到 这个指令执行时整个程序停顿了下来(没有使用非同步传送时),这时候电脑 便是在接收Server端传送来的资料,如果我们在传送资料的过程中查看一下硬 碟空间,会发现,空间正被用走,而且传送的过程时而会停个一下下。而这 rdUseOdbc的Cursor在Server端有没有做什麽动作呢?这个没有书有做说明,而 我认为Server端可能也会产生一个ForwardOnly的Cursor或者一个Tmp 的Table, 否则Server如何知道曾传过了多少资料给Cilent端是不是呢?(先前提过,并 不是在OpenResultset时便把所有资料传过来,而且在OpenResultSet时,会花 个一些时间才完成,时间的多少要看资料量与Sql的语法)。为什麽我会如此假设 呢,我做过一些Testing,如果Cursor的建立很容易,例如:Select * from testtab where id between 1 and 800 (而有在id上做Index),那麽,这个Cursor的 建立很快,一下子便可以传回Client端了;我们可以想像,这种Cursor我们可以 在Server端建一个ForwardOnly的Cursor,所以只要Fetch个某个数量的资料後, 便可传回Client了,所以速度快,等需要更多资料时便从目前Server端的Cursor 位置再继续读取下去。相反的,如果是Select * From testtab where fld2 = 'tt' order by fld3 (fld2, fld3上没有Index),这时候,就得在tmp Database中建立起该Table了,要不就得将所有Table中的Data都传到Client了, 我想,应是在Tmp Database中建Table比较像,所以这一类的Cursor在建立时 就要花较多的时间,相对的OpenResultSet的时间就会久。rdUseServer 和rdUseODBC相反,Cursor是在Server端建立,在Server端所建的Cursor和资料 库的特性就习习相关,我们如果查阅RDO的使用说明,会告诉我们Cursor又有分 Static, Keyset, Dynamic, ForwardOnly等等,但并不是所有的Database Server 都具有这个能力,例如说,SQL Server中就有所谓的Dynamic Cursor,这种 Cursor的特色在於:我们的Resultset建立完之後,别人新增了资料,只要该 资料在我们ResultSet的范围,我们也可以看得到它。然而,这种Dynamic的Cursor 在Informix 是没有提供的;但是一般来说,发展ODBC的厂商并不会在我们使 用Server 端没有提供的Cursor种类时,产生任何错误,取而代之的是,他们 会使用另一种较接近的Cursor来取代,例如说,对Informix Server使用Dynamic Cursor时,并没有产生错误,而其dynamic Cursor的行为和KetSet Cursor相同( 例:如果我们Server端是SQL Server,那使用Dynamic Cursor的Resultset,其 RowCount会传回-1 ,但如果Server端是Informix则传回实际的笔数)。使用 Server端的Cursor有好处也有坏处,好处等一下再说,先讲它的坏处,因为 Cursor要由Server来handle,所以多人使用时很浪费资源,尤其使用的Cursor 如果具有任意往前往後移动者(这叫Scroll Cursor),会在Server端的Temp database建立table,那花的时间与Resource会较多。rdUseServer所建的Cursor 如果是属於Scroll Cursor者(static, keyset, dynamic皆是)它会在Server端 将资料全准备好才算完成我们所下的OpenResultset的方法,如果资料量又大的话 ,那这个temp的table就会很大,可能会使我们的Resultset会造不出来。一般来 说,使用rdUseServer的Scroll Cursor在OpenResultset时花的时间会比rdUseODBC 的Scroll Cursor多,但是使用MoveLast时,刚好相反,因为Server端的Scroll cursor是使用Temp Database中所建立的Temp table,而这table在OpenResultset 时,便已完全的造出了。当然了,不管用Server/Client端的ForwardOnly Cursor (即OpenResultset使用rdOpenForwardOnly叁数),在OpenResultset时花的时间都 比较少,因为不必在Server端建立temp table;而的Cursor建立起来的速度(即 OpenResultset的速度)除了和是否是Scroll Cursor有关外,和所下的Sql指令与 RowSetSize这个属性有关。rdUseNone 字面上没有使用Cursor,不过我觉得在RDBMS中应仍旧是使用Server端的Cursor来 做,只是这种Cursor是ForwardOnly, ReadOnly,这类的Cursor不像Scroll Cursor 一定会在tmp Database中建立Table,所以Resource用得少,OpenResultset回应得 较快(建立快,且只Fetch一笔);因为OpenResultset方法会令Server端的Cursor 於Open Cursor後Fetch一笔资料,所以OpenResultset的速度快或慢,便取快於这 Fetch的速度了。而Client端呢,就真的没有Create Cursor来维护了。rdUseNone 的方式於只查寻没有修改、新增的情况中应是使用最多的一种,因它花费Server/ Client 的资源最少。使用它时,OpenResultSet只能使用rdOpenForwardOnly与 rdConcurReadOnly的搭配,不能使用其他搭配,而且其RowSetSize自动设成 1。注:以上皆是本人的试验与假设,若有问题敬请多多指正。 而如何设定Cursor是在Client端或Server端呢,那便得设定CursorDriver。如果没有设定,会使用内定的rdUseIfNeeded,而手动的设定要如此:1.如果在rdoConnection上设定CursorDriver属性,便得使用EstablishConnection方法 来做,如下: cn.CursorDriver = rdUseServer cn.EstablishConnection rdDriverNoPrompt, False sql = "Select * From qppfa" Set rs = cn.OpenResultset(sql, ....)2.如果在rdoEnvironment上设定CursorDriver属性,便得使用OpenConnection方法 来做,如下: en.CursorDriver = rdUseServer Set cn = en.OpenConnection("", rdDriverNoPrompt, False, connstr) sql = "Select * From qppfa" Set rs = cn.OpenResultset(sql, ....)注二: RowSetSize 是rdoQuery的一个属性,以下这一段是OnLine Help的说明RowsetSize 属性确定有多少笔索引键集 (Keyset) 的资料列被应用程序放入缓冲区中。RDO 使用RowsetSize 属性来确定有多少资料列被 ODBC 的 SQLExtendedFetch 函数读取到记忆体中。调整 RowsetSize 之大小,会影响到其性能以及为维护索引键集缓冲区所需的记忆体。如何,是不是每个字都懂,但是就是有看没有懂,说实在的,我也不敢说全懂,不过我做了一些Testing,这好像是:1.如果是rdUseODBC的Cursor,这影响ResultSet一次传回Client端的笔数,例如: ResultSet中一共有800笔资料,在OpenResultSet时(且不为rdOpenForwardOnly)时, 不会将这800笔Data一次传回,而是先传回RowSetSize所设定的笔数(如:100);等要读 第101笔时会再要求Server把101-200笔的资料传回来。所以了,如果Cursor的需Scan table才能知道有哪些Row符合条件时,RowSetSize也会影响OpenResultset所需的时间。2.如果是Server端的Cursor(rdUseServer),截录online help的说明 另外,当使用悲观锁定的 (rdConcurLock) 平行处理 (Pessimistic Concurrency) 时 ,RowsetSize 属性决定了有多少资料列(及其资料页)被锁定。例如,如果设定 RowsetSize 属性为 100 并且执行一个带有 rdConcurLock 选项的 rdoQuery 物件时 ,就锁定记录集的前 100 笔资料列以及和每一笔被锁定资料列相关的资料页,直到该资 料指标被关闭或将目前资料列指标移至该记录集的结束位置。在任何情况下,至少有 RowsetSize 笔资料列被锁定。 除此之外,RowSetSize也会影响Cursor建立後的一些特性,例如说,RowSetSize设为2 那代表OpenResultSet之後会读取两笔的资料,而此时的Current Record是第一笔,如果 尚未MoveNext到第二笔, 而第二笔资料被他人修改了(如果没有Tranaction而且是 rdOpenKeyset的ResultSet),那我们第一次下MoveNext後 (即指到第二笔资料),得到的 资料是未修改之前的Data,此时如果下Move 0的指令才会再得到最新的资料。相反的,如 果我们设RowSetSize = 1,而Cursor未指向第二笔前(即未MoveNext),第二笔资料被更 新了,而後的MoveNext会得到的是新的资料。3.rdUseNone则固定RowSetSize = 1注三: MaxRows的设定限制了ResultSet的最多笔数,但Informix的设定没有效

RDO 的建立记录集(一)

[ 1 ]
RDO 的建立记录集(一) num

打印本页 关闭

关于我们版权声明本站导航友情连结作品演示 TOP↑