⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlserver实例-2.htm

📁 微软数据库开发梦工场多媒体教学-sql server篇.rar,是多媒体教学的
💻 HTM
📖 第 1 页 / 共 4 页
字号:
        </OL>
        <font color="#000000">&nbsp;</font></TD>
    </TR>
  </TBODY>
</TABLE>
<P><font color="#FFFFFF">基于上述原因,Visual FoxPro在远程数据处理时强制使用缓冲技术。我们知道,在Visual FoxPro中缓冲技术与锁结合有四种选择:</font></P>
<TABLE width="100%" border=0>
  <TBODY>
    <TR> 
      <TD width="100%" bgcolor="#CCCCCC"> <LI> 
          <P 
        class=boe_list><font color="#000000"><font color="#000000">保守式行缓冲。所谓“保守”,就是“编辑时锁定”的意思,“行缓冲”是指“只缓冲处理一笔使用者加以编辑的数据记录”。因此一旦使用这种模式,当编辑动作刚开始,数据源的对应数据记录便被锁定,而且在执行以下两项动作时,数据变动才会被发送:移动数据指针、执行TABLEUPDATE()函数。<BR>
            由于在开始编辑时就锁定数据源的对应行,所以这种模式不被远程数据处理采用。 </font></font></P>
        <font color="#000000"> 
        <LI> 
          <P 
        class=boe_list><font color="#000000">开放式行缓冲。所谓“开放”,就是“更新时锁定”的意思,“行缓冲”是指“只缓冲处理一笔使用者加以编辑的数据记录”。因此使用这种模式,只有在执行以下两项动作时,数据变动才会被发送,数据源对应行记录才被锁定:移动数据指针、执行TABLEUPDATE()函数。 
            </font></P>
        <LI> 
          <P 
        class=boe_list><font color="#000000"><font color="#000000">保守式表缓冲。所谓“保守”,就是“编辑时锁定”的意思,“表缓冲”是指“缓冲处理整个使用者加以编辑的数据集(光标)”。因此一旦使用这种模式,当编辑动作刚开始,数据源的相关记录集便被锁定,而且在执行以下动作时,数据变动才会被发送:执行TABLEUPDATE()函数。<BR>
            由于在开始编辑时就锁定数据源的整个对应表或是记录集,所以这种模式不被远程数据处理采用。 </font></font></P>
        <font color="#000000"> 
        <LI> 
          <P 
        class=boe_list><font color="#000000">开放式行缓冲。所谓“开放”,就是“更新时锁定”的意思,“表缓冲”是指“缓冲处理整个使用者加以编辑的数据集(光标)”。因此使用这种模式,只有在执行TABLEUPDATE()函数时,数据变动才会被发送,数据源的相关记录集才被锁定。 
            </font></P>
        </LI>
        <font color="#FFFFFF"></font></font></font></TD>
    </TR>
  </TBODY>
</TABLE>
<P><font color="#FFFFFF">好了,我们得到以下结论:在操控远程数据时,Visual FoxPro将对光标采用“开放式行缓冲”或“开放式表缓冲”,默认设置是“开放式行缓冲”。</font></P>
<P class=boe_note><font color="#FFFFFF">以后在讨论远程数据处理时,不特别指出,行缓冲就是指开放式行缓冲,表缓冲是指开放式表缓冲。</font></P>
<P><font color="#FFFFFF">在“开放式行缓冲”下,因为只对一条被编辑的记录开启缓冲,所以有两种方式可以确认编辑、发送更新:移动指针(在上面的例子中我们已经使用过了)、TABLEUPDATE()函数。不知您能否理解“指针移动确认更新”的意思?我是这样理解的:行缓冲只对一条被编辑的记录有用,如果移动指针,那就必须确认更新(如果数据有变动),因为如果不确认更新(释放缓冲区),Visual 
  FoxPro便没法为下一行制定缓冲区了——记住:这是行缓冲。</font></P>
<P><font color="#FFFFFF">“在开放式表缓冲”下,Visual FoxPro对整个记录集开启缓冲区,所以移动指针并不会确认更新。只有使用TABLEUPDATE()函数了。</font></P>
<P><font color="#FFFFFF">乍一看,“开放式行缓冲”比“开放式行缓冲”需要更少的系统资源,好像是个好选择,我看不尽然:</font></P>
<TABLE width="100%" border=0>
  <TBODY>
    <TR> 
      <TD width="100%" bgcolor="#CCCCCC"> <OL>
          <LI> 
            <P class=boe_list><font color="#000000">有些Visual FoxPro的命令或函数会“不由自主”地移动指针,使得开发人员对更新的确认失去控制。 
              </font></P>
          <LI> 
            <P class=boe_list><font color="#000000">有时对数据的维护是成批的。 </font></P>
          </LI>
        </OL>
        <font color="#000000">&nbsp;</font></TD>
    </TR>
  </TBODY>
</TABLE>
<P><font color="#FFFFFF">下面的代码说明了怎样控制缓冲:</font></P>
<P><font color="#FFFFFF">USE VCustomers<BR>
  CURSORSETPROP("Buffering", 3, "VCustomers")<BR>
  *设定VCustomers的缓冲模式为“开放式行缓冲”。由于这时Visual FoxPro的默认设置,这一句可省略。<BR>
  USE VOrders<BR>
  CURSORSETPROP("Buffering", 5, "VOrders")<BR>
  *设定VOrder的缓冲模式为“开放式表缓冲”。</font></P>
<P><font color="#FFFFFF">以缓冲理解更新冲突</font></P>
<P><font color="#FFFFFF">在图8中我在发生更新错误时提示:“原先Phone=030-0074321,现在Phone=00000,两者不等……”,那么这个原先是“什么时候”,“现在”又是怎样的概念?(假设进程一、二采用行缓冲模式、用“关键字和已更新字段”检测冲突)。</font></P>
<P><font color="#FFFFFF">“原先”是指:进程一中视图被打开或是最近一次刷新成功时刻SQL Server数据表中的记录值。让我们先停下来,怎样才会刷新光标和缓冲呢?</font></P>
<TABLE width="100%" border=0>
  <TBODY>
    <TR> 
      <TD width="100%" bgcolor="#CCCCCC"> <LI> 
          <P class=boe_list><font color="#000000">远程视图光标被打开(无论使用行缓冲还是表缓冲)。 </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">成功执行REQUERY()函数(无论使用行缓冲还是表缓冲)。 
            </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">发送更新(无论成功与否) </font></P>
        </LI>
        <font color="#FFFFFF">&nbsp;</font></TD>
    </TR>
  </TBODY>
</TABLE>
<P><font color="#FFFFFF">您可以想象:进程一打开远程视图,Visual FoxPro自动把这个时刻SQL Server的数据值压入缓存中,这时进程一认为:我对SQL 
  Server上数据的修改应建立在这个基础上,即Phone=030-0074321,如果这个基础不存在了,这发生更新错误。</font></P>
<P><font color="#FFFFFF">在进程一还没有把它在客户端对Phone的修改发送到数据源的时候,进程二也读取了SQL Server的数据,注意这时进程二认为:我对SQL 
  Server上数据的修改应建立在这个基础上,即Phone=030-0074321。于是进程二修改Phone为00000,并在进程一之前确认的数据变动,这时是不会发生更新冲突的,因为进程二修改数据的依据是成立的。</font></P>
<P><font color="#FFFFFF">进程一慢慢吞吞地把数据改为了123456,发送更新。这时问题来了:进程一告诉SQL Server这样修改数据:</font></P>
<P><font color="#FFFFFF">sp_executesql N'UPDATE dbo.Customers SET Phone=@P1 WHERE 
  CustomerID=@P2 AND Phone=@P3', N'@P1 nvarchar(24),@P2 varchar(50),@P3 nvarchar(24)', 
  N'123456 ', 'ALFKI', N'030-0074321'</font></P>
<P><font color="#FFFFFF">我把参数填入,您就能很清楚地看到问题所在:</font></P>
<P><font color="#FFFFFF">UPDATE dbo.Customers SET Phone='123456'&nbsp; WH</font><font color="#000000">E<font color="#FFFFFF">RE 
  CustomerID='ALFKI' AND Phone='030-0074321'</font></font></P>
<P><font color="#FFFFFF">看到没有:Visual FoxPro自动的把 缓冲里的Phone=030-0074321(在BROWSE 
  窗口中您已经把Phone改为了123456,Visual FoxPro“早有预谋”,把原始数据存在缓冲中,任你表面变化万次——我都不怕)拿出来并结合关键字作为更新依据,然而由于进程二已经修改了Phone的值,在SQL 
  Server 中哪里还会有存在符合条件 CustomerID= 'ALFKI' AND Phone='030-0074321'的行了,只有CustomerID= 
  'ALFKI' AND Phone='00000'的记录行了。于是SQL Server 告诉 Visual FoxPro找不到目标记录,Visual FoxPro就对用户说:更新冲突。</font></P>
<P class=boe_sum><font color="#FFFFFF">所以,缓冲作用是就在这里:客户机与服务器通过 ODBC 这个翻译“传情达意”——但 
  ODBC 很苯——只能传一些SQL语句。事实上任何对数据的变动,都可归结为:Insert、Update、Delete。SQL语句与Visual FoxPro的命令函数有很大的不同——目标定位必须依靠条件语句(Where 
  子句)(Visual FoxPro可以很容易定位到第N行);缓冲为这些至关重要的定位条件提供了依据,没有缓冲就无法生成定位语句!</font></P>
<P class=boe_head2><font color="#FFFFFF">确认更新、放弃更新</font></P>
<P><font color="#000000">确认更新</font></P>
<P><font color="#FFFFFF">上文我们多次提到确认更新有基本上算是两种方式:移动指针、使用TABLEUPDATE()函数。移动指针只能在“开放式行缓冲“下使用,并且开发人员对法的可控性较差,一般用于交互式工具中,如上文我们使用过的SQL 
  Server 的Enterprise Manager工具。这里我们只讨论TABLEUPDATE()函数。</font></P>
<P><font color="#FFFFFF">在开放式行缓冲下使用TABLEUPDATE()函数:</font></P>
<TABLE width="100%" border=0>
  <TBODY>
    <TR> 
      <TD width="100%" bgcolor="#CCCCCC"> <LI> 
          <P class=boe_list><font color="#000000">语法:TABLEUPDATE(0[,lForce][,nWorkAear|cTableAlias]) 
            </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">返回值:更新成功——.T.,更新失败——.F. </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">必选参数:0。代表只更新当前记录到数据源——这里是记录缓冲,当然是:“只更新当前记录到数据源”。 
            </font></P>
        <LI> 
          <P 
        class=boe_list><font color="#000000">可选参数——lForce。默认为.F.,指:如果发生更新错误就确认更新错误,本函数返回.F.;如果设此参数为.t., 
            表示发生更新错误时,以本客户端的新值为准,覆盖网络上被确认已经的其他用户的更新,如果覆盖成功,本函数返回.T.。<BR>
            缺省表示本参数时取默认值。<BR>
            该参数设为.T.的实质就是<FONT 
        color=#ff0000>临时改变更新冲突的检测方式为“关键字段”,所以只要关键字不发生冲突,就不会发生更新冲突,本客户端的新值将覆盖其他用户做的变更。 
            </font></font></P>
        <font color="#000000"> 
        <LI> 
          <P 
        class=boe_list><font color="#000000">可选参数——nWorkAear|cTableAlias。表示实行TABLEUPDATE()的工作区,缺省表示对当前工作区有效。 
            </font></P>
        </LI>
        <font color="#FFFFFF"></font></font></TD>
    </TR>
  </TBODY>
</TABLE>
<P><font color="#FFFFFF">例如:</font></P>
<P><font color="#FFFFFF">USE VCustomers<BR>
  REPLACE PHONE WITH '123456'<BR>
  ?TABLEUPDATE(0)<BR>
  *返回 .T.更新成功,反之失败。</font></P>
<P><font color="#FFFFFF">USE VCustomers<BR>
  REPLACE PHONE WITH '123456'<BR>
  ?TABLEUPDATE(0,.t.,'VCostomers')<BR>
  *由于lForce设置为.t.,Visual FoxPro 临时修改更新检测方式为“关键字段”方式,所以只要关键字CustomerID不发生冲突,即使其他字段已经被其他用户修改,Visual 
  FoxPro也不会检测,Visual FoxPro将强制覆盖其它用户做的修改。<BR>
  *在“关键字段和已修改字段”的冲突检测方式下:Visual FoxPro向SQL Server发送如下语句:<BR>
  sp_executesql N'UPDATE dbo.Customers SET Phone=@P1 WHERE CustomerID=@P2', N'@P1 
  nvarchar(24),@P2 varchar(50)', N'123456', 'ALFKI'</font></P>
<P><font color="#FFFFFF">在开放式表缓冲下使用TABLEUPDATE()函数:</font></P>
<TABLE width="100%" border=0>
  <TBODY>
    <TR> 
      <TD width="100%" bgcolor="#CCCCCC"> <LI> 
          <P 
        class=boe_list><font color="#000000">语法:TABLEUPDATE(nRows[,lForce][,nWorkAear|cTableAlias][,cErrorArray]) 
            </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">返回值:更新成功——.T.,更新失败——.F. </font></P>
        <LI> 
          <P class=boe_list><font color="#000000">必选参数——nRows。可以有两种取值:1、2。假设用户对光标的第 
            1、2、4、5、7条记录作了修改,如果更新变动,第4条记录上将发生更新冲突。现在,执行本函数,Visual FoxPro将依次发送五条UPDATE-SQL描述:<BR>
            设本参数为1时,执行到第4条记录时发生更新冲突,Visual FoxPro将停止发送的5、7条记录的更新描述,并使本函数返回.F.值,Visual 
            FoxPro的记录指针停留在第四条记录上。<BR>
            设本参数为2时,执行到第4条记录时发生更新冲突,Visual FoxPro将继续发送的5、7条记录的更新描述,并使本函数返回.F.值,Visual 
            FoxPro的记录指针最终停在最后一条被修改的记录上(这里是第7条记录)。如果可选参数——cErrorArray存在,Visual 
            FoxPro将把发生更新错误的记录号(RECNO())写入该数组,如果第5条记录也发生冲突,那么该数组将是一个一列两行的数组,cErrorArray[1]=4、cErrorArray[2]=5 
            </font></P>
        <LI> 
          <P 
        class=boe_list><font color="#000000">可选参数——lForce。默认为.F.,指:如果发生更新错误就确认更新错误,本函数返回.F.;如果设此参数为.t., 
            表示发生更新错误时,以本客户端的新值为准,覆盖网络上被确认已经的其他用户的更新,如果覆盖成功,本函数返回.T.。<BR>
            缺省表示本参数时取默认值。<BR>
            该参数设为.T.的实质就是<FONT 
        color=#ff0000>临时改变更新冲突的检测方式为“关键字段”,所以只要关键字不发生冲突,就不会发生更新冲突,本客户端的新值将覆盖其他用户做的变更。 
            </font></font></P>
        <font color="#000000"> 
        <LI> 
          <P 
        class=boe_list><font color="#000000">可选参数——nWorkAear|cTableAlias。表示实行TABLEUPDATE()的工作区,缺省表示对当前工作区有效。 
            </font></P>
        <LI> 
          <P 
        class=boe_list><font color="#000000">可选参数——cErrorArray。这是一个一列数组,且只有当必选参数nRows为2时有效,这时它记录着发生更新冲突的记录的记录号;如果没有发生任何更新冲突或是当必选参数nRows不为2时,本数组为一行一列,值为-1。 
            </font></P>
        </LI>
        <font color="#FFFFFF"></font></font></TD>
    </TR>
  </TBODY>
</TABLE>
<P class=boe_list><font color="#FFFFFF">举个例子:(假设使用“关键字段和已修改字段”作为更新冲突检测方案)</font></P>
<P><font color="#FFFFFF">USE VCustomers<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -