标题：vfp
简介
VFP(Vector Floating-point Coprocessor for ARM)向量浮点运算单元(协处理器)
VFP除了提供浮点数基本运算（加、减、乘、除、开方、比较、取反）提供支持之外，最有特点是它向量（vectors）功能。它同时支持最多8组单精度4组双精度浮点数的运算。有关这部分的叙述请参考<<ARM Architecture Reference Manual>> Chapter C5 VFP Addressing Modes。
特性
FoxBase采用命令行方式（为了和当时流行的数据库软件dBase兼容……）但是速度比当时其他的数据库软件要快。
由于其为32位的数据库开发系统且具有良好的跨平台特性，它可以运行于Windows95/98/2000/XP/Visita/7等操作系统之上。
成长之路
Visual FoxPro（以下简称VFP）是个不断成长的小伙，承蒙Visual Studio（以下简称VS）的关照，VFP在开发者心目中一直是和VB、VC地位相同的工具语言，只不过它并不是通用开发工具，而只是专注于数据库应用的开发。
然而，吊足大家胃口的VS. NET终于出现在开发者面前时，竟不见了VFP的身影，着实引起开发社区的一阵骚动。微软不要VFP了？不是，恰恰相反，VFP忍受不了VS缓慢的升级速度，“单干”了。现在的VFP已经升级到版本9，并且完全支持.NET技术。VFP 6Visual FoxPro 6.0及其中文版，是可运行于Windows 95和Windows NT平台的32位数据库开发系统，它不仅可以简化数据库管理，而且能使应用程序的开发流程更为合理。Visual FoxPro 6.0使组织数据、定义数据库规则和建立应用程序等工作变得简单易行。利用可视化的设计工具和向导，用户可以快速创建表单、查询和打印报表。 
Visual FoxPro 6.0还提供了一个集成化的系统开发环境，它不仅支持过程式编程技术，而且在语言方面作了强大的扩充，支持面向对象可视化编程技术，并拥有功能强大的可视化程序设计工具。目前，Visual FoxPro 6.0是用户收集信息、查询数据、创建集成数据库系统、进行实用系统开发较为理想的工具软件。VFP 7Web Services支持 VFP 7支持注册和发布Web Services，而无需使用Microsoft SOAP Toolkit和VFP扩展来从底层完成这些任务；
服务器增强 VFP 7对于COM服务器作了很大程度的增强，可以与核心平台如COM+服务进行互操作；
XML支持 为了适应以XML形式在Web上传送数据的潮流，VFP 7提供了一些函数用于在XML数据和FoxPro游标（Cursor）或表格（Table）之间的转换。
多样的XBase特性 VFP添加了很多新的或改进的XBase特性，并且这些特性都是用VFP语言编写的；
OLE DB Provider 通过实现OLE DB Provider接口，开发者可以在任何支持OLE DB的程序和语言中调用VFP数据。VFP 8n 数据特性增强 VFP 8对其数据特性进行了改进，并增加了很多新的数据特性，包括：远程数据连接、创建DataEnvironment类、自动增长域值、支持对照序列、与SQL语句Select…Union之间的隐式数据转换、使用SQL Select命令插入行等；
其他增强 VFP 8对一些工具、示例数据库和解决方案案例都进行了改进。VFP 9数据和XML增强 这一时期的VFP对其数据特性进行了巨大的加强，改进项目之多真是令人眼花缭乱，详情可以参考这里，此处不再赘述；
实现SQL语言 VFP 9已经能够充分地支持SQL查询语言；
设计器的增强 VFP 9增强了这些设计器：报表和标签设计器、菜单设计器、表格设计器、查询和视图设计器、数据环境设计器以及类和窗体设计器等；
其他方面的增强 和VFP 8一样，VFP 9在其他微小的细节上进行了不少的改进，使得开发者的体验更加舒适。后续微软已经于，2007年前后，宣布 Visual Foxpro 停止研发，VFP9 是最后一个官方版本。微软在曾经2007年3月份的时候声称，将会对 Visual Foxpro 开放源代码到，其代码共享社区站点CodePlex上，但是截止到2010年4月，在CodePlex似乎似然搜索不到Visual Foxpro的源代码。
日前，在微软官方网站释出了一份公告A Message to the Community，说明未来将不会再推出 VFP 10，并且持续 VFP 9 的支持到 2015 年，之后只会在 2007 年夏季推出 SP2。2006年进行的 Sedna 项目则是增强VFP对SQL Server 2005与 Vista的支持，其他的一些项目则已经开源到CodePlex。
需要注意
SPT的全称为SQL Pass-Through，它和远程视图（Remote View）、CA（CursorAdapter，VFP8及后序版本支持）共同构成了VFP实现数据库操作的利器。远程视图及CA实质上都是基于SPT技术，与它们相比，SPT要更为灵活，它可以直接创建数据库接连，执行数据库原生SQL语句，并可以获取临时表（Cursor），通过设置能使对临时表的更改更新到数据库表中。SPT的缺点是不面向对象、代码量大。1. 与数据库建立连接VFP可以通过SQLCONNECT()函数或SQLSTRINGCONNECT()函数可以和任何支ODBC驱动的数据库建立连接，成功建立连接后将返回一个大于0的整数型句柄，如果连接失败则会返回-1。通过这个句柄我们可以用SQLEXEC()函数向数据库发送SQL语句，最后需要调用SQLDISCONNECT( )函数断掉连接。
例1：假设已存在一个名称为MyNewDB的数据源，用户名是sa，密码是admin，使用SQLCONNECT()函数创建数据库连接。
LOCAL lnHandle
lnHandle = SQLCONNECT("MyNewDB", "sa", "admin")
? "已成功创建数据库连接，连接句柄是：", lnHandle
= SQLDISCONNECT(lnHandle)
例2：连接位于192.168.0.100的某台SQL Server数据库服务器上的MyNewDB数据库，，用户名是sa，密码是admin，使用SQLSTRINGCONNECT()函数创建数据库连接。
LOCAL lcConnStr, lnHandle
lcConnStr = "Driver=SQL Server;Server=192.168.0.100;" + ;
:Database=MyNewDB;UID=sa;PWD=admin"
lnHandle = SQLSTRINGCONNECT(lcConnStr)
IF lnHandle > 0
= MESSAGEBOX("数据库连接成功。", 64, "提示信息")
= SQLDISCONNECT(lnHandle)
ELSE
= MESSAGEBOX("数据库连接失败。", 48, "提示信息")
ENDIF　2. 如何向服务器取数据在第一步建立和服务器数据库的连接,并取得连接句柄nhandle后 
sqlexec（jb,"select * from tablename","cursorname"）3. 如何向服务器取数据如向服务器表employees查询性别为男的人员 
在第一步建立和服务器数据库的连接,并取得连接句柄nhandle后 
sqlexec（nhandle,"select * from employees where sex=’男’","employees"） 
select employees 
brow 
也可以调用系统上的存储过程来取得数据. 
如在服务器建立存储过程 
create proc getmanofworkes 
as 
select * from employees where sex=’男’ 
go
然后在vfp里调用 
sqlexec(nhandle,"exec getmanofworkes",employees) 
select employees 
brow
当然也可以想存储过程传递参数查询 
仍然以刚才的例子,查询不同性别的员工 
在服务器上建立create proc getemployees 
@sex char(2)=’男’ 
as 
select * from employees where sex=@sex 
go 
vfp里调用 
查询男员工 
csex=’男’ 
sqlexec(nhandle,"exec getemployees ?sex",’employees’) 
select employees 
brow 
查询女员工 
csex=’女’ 
sqlexec(nhandle,"exec getemployees ?sex",’employees’) 
select employees 
brow 
这时brow得到的cursor你会发现,虽然修改了表中的数据，但服务器上并没有被更新. 
这是因为spt得到的光标默认是可写但不可更新的。
设置本地表可更新服务器表
sqlexec(jb,"select id,bh,hyzhm,fzdw,rghsj,ghzrsj,xm,xb,gs_bm from rsda where lcbj=0 order by gbbh","gh") 
***设置gh可更新rsda表 
sele gh 
cursorsetprop("tables","rsda","gh") &&设置临时表的更新目标表 
cursorsetprop("keyfieldlist",’id’,"gh") &&设置临时表的关键字 
cursorsetprop("updatablefieldlist","id,fzdw,rghsj,ghzrsj,hyzhm","gh")&&设置临时表的更新字段
cursorsetprop("updatenamelist","id rsda. id,hyzhm rsda.hyzhm,rghsj rsda.rghsj,ghzrsj rsda.ghzrsj,fzdw rsda.fzdw","gh") 
&&&用gh中的相应字段更新rsda表 
cursorsetprop("sendupdates",.t.,"gh")&&设置为可更新 
cursorsetprop("wheretype",2) 
cursorsetprop("buffering",5)&&设置表缓冲 
顺便提一下，表缓冲必须有明确的tableupdate命令才能更新。 
上面的功能都是通过本地的cursor来处理远程数据。spt还可以直接处理远程数据。 
如将远程服务器上的表rsda中，性别为男的，都改成女的。 
sqlexec(nhandle,"update rsda set xb=’女’ where xb=’男’")&&由于这句是更新命令，不需要返回一个记录集，所以，第
三个参数，光标名可以省略不写。
由此也就可以举一反三的明白，如何调用远程存储过程来更新数据了。 
如将上面的更新语句写成存储过程 
在服务器上 
create proc updatesex 
as 
update rsda set xb=’女’ where xb=’男’ 
go 
vfp调用 
sqlexec(jb,"exec updatesex")&&调用存储过程，不需要返回光标，取消第三个参数 
如何开始一个远程事务 
事务它包含一个可回滚的操作段。在sql server上在事务中的数据，并没有实际的写入数据库，而是将更新临时存储在
缓冲中，只有明确的发出了commit或者rollback tran才结束这个事务，将操作取消或者将操作实际写入。 
每个事务以begin tran开始，以commit tran或者rollback tran结束。倘若在遗漏了commit tran或者rollback tran，在sql server就很容易的表现为等待状态，即死锁状态，在等待该事务的释放。 
开始一个事务： 
sqlexec(nhandle,"begin tran")&&开始一个事务，事实上sqlexec()中的第二个参数中的操作都是被发送到sql server执行的。这样也就可以理解存储过程的一个优点，因为存储过程只要发送一个调用语句给服务器，而如果将这些语句全部写在
VFP端，则带来的网络传送量必然很多，客户端越多，造成网络阻塞的可能就越大。回到事务上来。 
sqlexec(nhandle,"insert into tablename values()") 
sqlexec(nhandle,"if @@error<>0") 
sqlexec(nhandle,"begin") 
sqlexec(nhandle,"rollback tran") 
sqlexec(nhandle,"return") 
sqlexec(nhandle,"end") 
sqlexec(nhandle,"delete from tablename where ") 
sqlexec(nhandle,"if @@error<>0") 
sqlexec(nhandle,"rollback tran") 
sqlexec(nhandle,"else") 
sqlexec(nhandle,"commit tran") 
当然在vfp8中可以写成text endtext的形式更加直观
不过我个人感觉，有事务处理的处理还是最好写成过程。例在服务器上建立过程
create proc procname 
as 
begin tran 
insert into tablename values() 
if @@error<>0 
begin 
rollback tran 
return 
end 
delete from tablename where 
if @@error<>0 
rollback tran 
else 
commit tran 
在vfp端sqlexec(nhandle,"exec procname") 
当然也可以开启服务器事务： 
* 开始一个 VFP 事务处理和一个服务器上的事务处理. 
nConnection=CursorGetProp("ConnectHandle","mytable") 
SQLExec( nConnection, ‘BEGIN TRANSACTION’ ) 
* 更新修改到 MyTable. 
lEverythingOK = Tableupdate( 2, .F., ‘mytable’ ) 
If lEverythingOK 
* 更新修改到 MyOtherTab[1]