学习vfp好久,但是这个spt/ca 不太解.请教!
http://blog.csdn.net/fyfcom/article/details/5688990 这是一个贴子. 我正在学习中.......
以下红色的是我的问题.
***********************以下是我改装后连接access中的文件
&&&&&&&&&& SPT 方式
*!*lcConnectString = "Provider=Microsoft.Jet.OleDB.4.0;DataSource=DB1.mdb"
&& 我在delphi asp 中连接就用此串在VFP中要使用下面的串
lcConnectString="Driver={Microsoft Access Driver (*.mdb)};dbq=db1.mdb;pwd=;uid=;"
nhandle=SQLSTRINGCONNECT(lcConnectString) &&pwd为数据库密码项
IF nhandle <=0
MESSAGEBOX("数据库连接失败!!!",16, '错误信息')
RETURN
ELSE
Ac=SQLEXEC(nhandle,"Select * From address","address")
IF Ac <0
MESSAGEBOX("读取数据错误!",16, "错误信息")
ELSE
SELECT address
BROWSE
APPEND BLANK
REPLACE name WITH "tt" &&这里添加并改变 一关闭就没有了 因为他们是 cursor !
INSERT INTO address (name,address) VALUES ("abc","abcd") &&这里添加并改变 一关闭就没有了 因为他们是 cursor !
BROWSE
*如何让上述两次改动保存在数据库呢?
*这个spt 全称是什么
&& 如何执行 sql 命令
&& 如何执行 存储过程
ENDIF
ENDIF
SQLDISCONNECT(nhandle)
&&&&&&&&&&&&&&&&&&&&& CA
lcConnString = "Driver={Microsoft Access Driver (*.mdb)};dbq=db1.mdb;pwd=;uid=;"
loCursor = createobject('CursorAdapter')
with loCursor
.Alias = 'address'
.DataSourceType = 'ODBC' && 这里为何不写 ado
.DataSource = sqlstringconnect(lcConnString)
.SelectCmd = "select ID,name,address from address"
.KeyFieldList = 'ID'
.Tables = 'address'
.UpdatableFieldList = 'name,address'
*.UpdateNameList = 'CONTACTNAME CUSTOMERS.CONTACTNAME'
.UpdateNameList = 'address address.address,name address.name'
if .CursorFill()
&&&&以下没有执行!
BROWSE
APPEND BLANK
REPLACE name WITH "tt"
INSERT INTO address (name,address) VALUES ("abc","abcd")
&&如果执行成功,我想添加记录怎么办?
&& 如何生成 记录集 && 比如不是表中全部数据的记录集
&& 如何执行 sql 命令
&& 如何执行 存储过程
ELSE
&& 这里执行啦
MESSAGEBOX("TT")
ENDIF
.CursorFill() &&这里为什么又加一句
ENDWITH
RELEASE loCursor
http://blog.csdn.net/fyfcom/article/details/5688990 该贴子中对 CA 这样说:
这里是上面的最后一个观点的例子。假设你有一个使用 CursorAdapter 通过 ODBC 来访问 SQL Server 数据的应用程序,由于某些原因你想要改成使用 ADO 了。对于这种情况,你只需要改动 CursorAdapter 的 DataSourceType 属性、并改变对后台数据库的连接,就全部完成了。你的应用程序中的其它部分不需要知道也不需要关心这些事情;它们看到的只是同一个 Cursor 而不管使用了哪一种机制。
属性
我们先从查看 CursorAdapter 的属性、事件和方法开始来学习它。这里不会讨论所有的属性,只谈一下最重要的那些。
DataSourceType
**************
这个属性是最重要的:它决定了这个类的表现,以及要在其它一些属性中要怎么设置。可用的选项有“Native”——意思是使用 VFP 表——或者是 "ODBC"、"ADO" 或 "XML" ,表示你要选用的访问远程数据源的方式。
ODBC 如何连接
ADO 如何连接
XML 如何连接
DataSource
***********
这是访问数据的手段。当 DataSourceType 被设置成“Native”或者“XML”的时候,VFP会忽略这个属性的设置。对于ODBC,请把这个属性设置为一个有效的 ODBC 连接句柄(这意味着你要自己管理连接了)。在ADO的情况下,DataSource 必须是一个 ADO RecordSet,而且它的 ActiveConnection 对象必须被设置为一个打开的 ADO Connection 对象(你又要自己管理这些了)。
如何采用 ado 如何设置 ado recordset ado connectionUseDEDataSource
****************
如果这个属性被设置成了 .T.(默认是 .F.),你可以不管它的 DataSourceType 和 DataSource 属性,因为 CursorAdapter 将使用 DataEnvironment 的属性来代替( VFP 8 给 DataEnvironment 也增加了 DataSourceType 和 DataSource 属性)。举例来说,当你想让在一个数据环境中的所有 CursorAdapters 斗使用同一个 ODBC 连接的时候,就可以把它设置为 .T.。
SelectCmd
**********
除了 XML 的情况以外,这是一个用来取得数据的 SQL Select 命令。在 XML 的情况下,它可以或者是一个能够被转换为一个 Cursor 的有效 XML 字符串(使用内部的 XMLTOCURSOR() 调用),或者是一个能够返回一个有效的 XML 字符串的表达式。
CursorSchema
************
这个属性里保存的是 Cursor 的数据结构,格式就像你在用 CREATE CURSOR 命令的时候用的那样。这是一个例子:CUST_ID C(6), COMPANY C(30), CONTACT C(30), CITY C(25)。尽管不设置这个属性而让 CursorAdapter 在自己建立 Cursor 去决定这个结构也是可以的,不过如果你自己输入的话,它会工作的更好。如果 CursorSchema 是空的或者不正确,那么当你打开一个表单的数据环境的时候,就会要么弹出一个错误,要么就不能通过从 CursorAdapter 中拖放字段到表单上来建立控件。幸运的是,VFP 自带的 CursorAdapter 生成器可以为你填充这个属性。
AllowDelete、AllowInsert、AllowUpdate 和 SendUpdates
在哪儿修改这些属性.
****************************************************
这些属性的默认值是 .T.,它们决定了是否可以删除、插入和更新和改动是否要被发送到数据源。
KeyFieldList、 Tables、 UpdatableFieldList、和 UpdateNameList
在哪儿修改这些属性.
*************************************************************
这些属性的用途跟 CURSORSETPROP() 中用到的那些参数的用途是一样的,如果你想让 VFP 自动将对 Cursor 的改动提交到数据源,这些属性就是必须的。
[解决办法]
INSERT INTO address (name,address) VALUES ("abc","abcd")
改为
SQLExec(nhandle,"Insert Into address (Name,address) Values ('abc','abcd')")
[解决办法]
SPT 是 SQL Pass-through 的缩写
[解决办法]
SPT 主要有13条语句,是VFP和其它数据库(例如MSSQL)通讯的主要语句,使用非常灵活,是VFP建立C/S的主要实现方式之一,但是我建议楼主尽快转行学习WEB/SERVER架构,语言使用JAVA或C#都行,VFP到时可以学习做中间件,SPT是制作中间件的最理想的技术之一
[解决办法]
如果没有C语言基础,想学好WEB/SERVER,据我的经验,学习的过程应该是:HTML-CSS/DIV-DREAMWEAR-FIREWORK-FLASH-C#/JAVA推荐几本好的学习书籍,明日科技的相关书籍,网上的W3C的WEB知识,等。只要目标明确,遇到问题就多谷歌,缺哪攻哪,很快就可以做项目了
[解决办法]
我给你大概说一下SPT的全过程(只涉及主要操作的相关函数),看完成之后应该就清楚了。
一、连接数据库
public con
con=SQLSTRINGCONNECT("driver=sql server;server=SQL数据库服务器计算机名或者IP地址;uid=sa;pwd=you password;database=数据库名称")
当CON小于0时表示连接失败。
二、执行sql命令
VFP的SPT命令并不像ADO那样分得有好几个执行命令,如ADO的非查询的,查询的,只返回第一条记录的查询命令。它的命令执行格式统一如下:
SQLEXEC(con,"命令字符串")
con为连接句柄,命令字符串可以是SQL 数据库服务器支持的任何命令,如果命令字符中超过255个字符,请采用多个字符串拼接的方式,否则VFP将出不能识别的命令的提示。命令字符串可以select\update\insert命令,也可以是执行存储过程的命令。
三、获取数据库上的数据
sqle(con,"select * from test","test")
该句含义为在数据库服务器上查询TEST数据表,并返回到VFP客户端成为一个临时表,临时表名为test,当然你也可以指定任意一个临时表名称。这里只为方便表述,取名为TEST而已。
一旦获取到结果集,你就可以像使用本地VFP的表一样去使用这个临时表,包括insert\update等命令的执行,但是你如果在没有设置该表为更新的时候,这些改动将不会被保存到服务器上的表中。
注意:临时表不能更改数据表结构,同时这里的临时表的另一说法也被称为游标或者远者远程视图。不同于VFP本地表的临时表,VFP的本地临时表是可以修改数据表结构的,且限制更少,其它操作同本地临时表差不多。
四、设置临时表为可更新
设置临时表可更新一般由cursorsetprop函数来进行设置,该函数除具体功能请参考帮助。设置临时表为可更新一个分成五个步骤:
1、关联数据库表和第三步获得的临时表
cursorsetprop(“tables”,”数据库表名”,”临时表”)
如cursorsetprop(“tables”,”test”,”test”)
2、要更新的关键字列表
其实就是指表的改动依据哪些键作为依据来更改数据库服务器中的表,它的格式如下:
cursorsetprop(“keyfieldlist”,服务器中的主键字段列表,”临时表名称”)
如果数据库服务器中的表没有主键,且没有唯一名称字段,那么请设置主键字段;如果数据库服务器表中有多个主键字段(几个字段组合成为主键),那么格式中的主键字段列表直接用逗号分开即可。如:
cursorsetprop('keyfieldlist',”id,code”,”test”)
这里我假设了TEST有一个id与code组成而成的关键字。
3、设置临时表可更新的字段名称列表
设置临时表中要更新的字段列表。格式如下:
CURSORSETPROP("UpdateNameList" ,”临时表中可更新到远程服务器表的字段名列表”,”要更新的临时表名”)。
如cursorsetprop(“updatenamelist”,”id,code,xm”,”test”)
4、关联服务器上的表和VFP中的临时表可更新的字段
设置可更新的字段的意思是指数据库服务器上的表中的那些字段可以在VFP表中改动后,同时作出相应的更改。格式如下:
cursorsetprop(“updatenamelist”,”用逗号分隔的要关联的字段列表”,”VFP表的临时表名称”)
用逗号分隔的要关联的字段列表格式如下:
VFP临时表字段名 数据库表名称.字段名, VFP临时表字段名 数据库表名称.字段名,…
如果数据库表中有50个字段需要更新,那么这50个字段都必须一一对应,如果只需要更新其中一两个字段,那么只需要对应要更新的两个字段即可。总之,想要在VFP改动之后,数据库表也相应改动,则必须一一对应,否则将不能同步改动。如
cursorsetprop(“updatenamelist”,”id test.id,code test.code,xm test.xm”,”test”)
如果在获取数据库上的数据使用了如下命令:
sqle(con,”select id 标识,code 编号,xm 姓名 from test”,”test”)
那么,上述所有涉及到临时表字段名称需设为你映射过来的字段名称,所有涉及到服务器表中的名称要为原来的名秒,不可使用映射的名称。
如:cursorsetprop(“updatenamelist”,”标识 test.id,编号 test.code,姓名 test.xm”,”test”)
这一步同第4步操作差不多,只是多了一个多远程服务器上的表的字段关联。
5、设置VFP临时表为可更新的表
这一步最重要,这一步没有做的话,前面的几步全部白做。它的格式如下。
CURSORSETPROP("sendupdates",.t.,”临时表名称”)
如:cursorsetprop(‘sendupdates”,.t.,”test”)
本大点小结:
如果你没有设置这5步,那么,你获取的临时表将是不可更新的,但它仍然可以执行修改,删除,添加等操作,但这些操作随着临时表的关闭而丢弃,将不会保存到数据库服务器表中。这五步最麻烦的就是第三步和第四步,如果一个表中,有100个字段,那么你就要对应100个字段,没有像ADO那样的更新命令自动构造器,但你可以将上述步骤写成一个通用的函数,以后直接调用该函数即可自动完成上述五步设置。如我自己就写成了一个UPTMP(意为更新临时表)的函数,当我获取一个表之后,调用上述函数即可。如在上述介绍中我获取了临时表,仅需执行uptmp(“test”,”test”,”id,code)函数后,就完成了更新设置。
上面的例子获取的表的更新是适时的,当你修改了一条记录,并且移动记录指针之后,你所做的修改都将会保存到服务器中,接下来将说一下表的缓冲。
五、临时表的缓冲与保存和放弃修改
正如上文所述,当你修改一条记录并且移动了记录指针,那么你所做的修改将立即反应到后台数据库服务器中,但有时我们需要反复修改一条记录,这样就会造成前端应用程序频繁访问后台数据库,造成服务器压力,同时还不方便用户控制数据的保存和放弃保存的时机。利用缓冲技术可以有效的解决上述问题。
缓冲就是VFP将所做的修改暂时缓存到本地,当你发出提交更改的时候,VFP将你所做的修改保存到后台数据库,当你放弃修改时,VFP将还原至你上次提交更改时的状态。
1、设置缓冲
cursorsetprop(“buffering”,缓冲模式,”临时表名”)
缓冲模式为1至5的数字,1为关闭缓冲,5为乐观缓冲(我一般只用5,所以这里只讲5,其它的缓冲模式请参考帮助)。如:
CURSORSETPROP("Buffering",5,"test")
2、提交更改
示例:
sele test
if !tablesupdate(.t.)&&提交更新,成功返回.t.,否则返回.f.,失败后请进行相应的错误处理
aerror(ermsg)
messagebox(ermsg(2),64,”保存错误”)
else
messagebox(“保存成功”,64,”提示”)
endif
3、放弃更改
sele test
if !tablerevert(.t.)&&放弃更新,成功返回.t.,否则返回.f.,失败后请进行相应的错误处理
aerror(ermsg)
messagebox(ermsg(2),64,”错误”)
else
messagebox(“放弃更新成功”,64,”提示”)
endi
4、当网络连接中断后,关闭应用程序时经常出出不能退出VISUAL FOXPRO或者有无效的连接句柄时,你就可以使用放弃更改,将在缓存在的数据删除后在退出。有效避免不能退出的尴尬情况。
六、执行存储过程
同执行普通的命令一样,如:sqlexec(con,”exec dbo.后台数据库存储过程名”)。
如果存储过程有返回结果集的命令,那么上述命令还可以加一个临时表名称来接收该存储过程返回的结果集。如:
sqle(con,”exec dbo.存储过程名”,”temp”)
七、SQL命令参数
这里将通过示例讲解如何将VFP中的变量传递给SQL数据库。
如我们想在TEST表中查询学生成绩大于指定分数的学生姓名。其命令如下:
select name from test where score>你指定的分数(假设TEST表中含有SCORE字段),这时我们为其编写了一个存储过程,名称为cjcx,该存储过程有一个输入参数,表示指定的分数。那么在VFP中的查询方式为。
示例:
tmepscore=thisform.text1.value&&将你输入的学生分数赋值给临时变量
sqle(con,”exec dbo.cjcx ?tempscore”,”temp”)&&用?号加临时变量名称来传递
执行该存储过程后,存储过程返回的结果集将存到temp表中。
注意:如果存储过程有多个参数,传递参数时必须与存储过程的输入参数一一对应,且数据类型相同可者可隐式转换,多个参数之间用逗号隔开。
也可以使用一条普通命令来满足上文要求的查询:
sqle(con,”select name from test where score>?tempscore”,”temp”)
八、关闭连接
sqldisconnect(连接句柄),如:sqldisconnect(con)
九、其它
其它的还有处理多个结果集,即批处理,事务处理等将不再一一介绍,请参考帮助手册。
十、总结
到这里,这是一个完全的应用流程。SPT大概操作就这么多,其它的就是事务,事务用SQLSETPROP函数设置,请查询相关帮助。至于多个结果集很少使用,其它的设置也很少用到。到这里,就可以满足你的基本需要了。
[解决办法]
我是以SQL SERVER为例进行说明的,文笔不太好,将就看,另外,示例中的符号可能有中文的符号,请注意。无论你使用的是ACCESS还是SQL SERVER,都差不多,区别就是看各自的数据库内部支持的命令格式,但一般情况下的增、删、改、查都差不多。另外,临时表设为可更新后,要增加记录可以插入记录,也可以APPNED,要删除记录时直接DELETE,但是临时表是没有PACK这条命令的,只要执行DELETE后就直接删除了。临时表也可以使用INDEX索引,同样也可以使用SELECT * from 临时表的语句,跟使用本地表一样。
[解决办法]
用【spt】方式,就是直接调用sql server的sql语句,跟操作sql server一模一样,强烈建议用spt方式操作。