vfp如何使用spt

流星尔 2003-08-04 02:20:27
加精
spt的全称为sql pass through,它是和远程视图构成了vfp处理远程数据的利器。和远程视图比较,它的主要好处在于灵活,可以直接连接远程数据库,并在服务器上执行代码代码, 当然它也可以和远程视图一样,通过一个光标cursor来更新远程数据,缺点主要是非图形化,代码量大。实际上远程视图是SPT的一个子集。

步骤:
1、建立连接,或者连接句柄
如连接服务器为aa,用户名为bb,密码为cc,数据库为dd
nhandle=sqlstringconnect("driver=sql server;server=aa;uid=bb;pwd=cc;database=dd")
if nhandle>0
messagebox("数据库连接成功!",0,"提示")
else
messagebox("数据库连接成功!",0,"提示")
endif

...全文
684 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
coolyylu 2003-08-06
  • 打赏
  • 举报
回复
good
流星尔 2003-08-06
  • 打赏
  • 举报
回复
大家看一下有没有什么补充的,如果没有补充的,就结贴为FAQ了。
chjpeng 2003-08-06
  • 打赏
  • 举报
回复
好東東,收藏!
trainee 2003-08-06
  • 打赏
  • 举报
回复
VFP的SPT确是好用,但也有不足之处
没有返回SQLROWCOUNT的语句.
比如SQLEXEC(“UPDATE XXX SET 。。。”)
你无法得到到底UPDATE了几个记录.

我想VFP的内部调用肯定有用到此函数,否则TABLEUPDATE就无法检测到"数据被更改"的错误,
只是没有把这函数公开.
建议VFP在VFP9.0能改进.

xiolig 2003-08-05
  • 打赏
  • 举报
回复
贺:楼主重新执掌 VFP 论坛!
xiolig 2003-08-05
  • 打赏
  • 举报
回复
我猜测 SQLEXEC 只是把命令串原样送给服务器,从而导致服务器接收参数查询出错。
若是这样,把参数(如?gg)替换为常量(如宏替换等)。
unlist 2003-08-05
  • 打赏
  • 举报
回复
學習
qufusongyu 2003-08-05
  • 打赏
  • 举报
回复
当然也可以开启服务器事务:
* 开始一个 VFP 事务处理和一个服务器上的事务处理.
nConnection=CursorGetProp("ConnectHandle","mytable")
SQLExec( nConnection, 'BEGIN TRANSACTION' )
* 更新修改到 MyTable.
lEverythingOK = Tableupdate( 2, .F., 'mytable' )
If lEverythingOK
* 更新修改到 MyOtherTable.
lEverythingOK = Tableupdate( 2,.F.,'MyOtherTable')
endif
* 结束服务器上的和 VFP 的事务处理.
If lEverythingOK
SQLExec( nConnection, 'IF @@TRANCOUNT > 0 COMMIT' )
End Transaction
Messagebox('数据保存成功!',64,'提示',2000)
Else
SQLExec( nConnection, 'IF @@TRANCOUNT > 0 ROLLBACK' )
endif
流星尔 2003-08-05
  • 打赏
  • 举报
回复
这个应该跟vfp没什么关系,而是在你数据库的设计问题上。查询这种错误的最简单方法就是
直接在查询分析器中执行insert student (id, da, score) values ('aa', getdate(),5),看出现什么错误。
我想这个错误应该就是你的另一个字段是不允许空的,而你没有在INSERT中指定它的值,错了,或者唯一索引了,结果你重复了,或者有外键的约束,这些问题,你只要在查询分析器运行一下,就可以知道错误了。
而如果你在查询分析器中执行把参数的值放入SQL SERVER,而并没有出现错误时,请查看VFP中传递的参数类型,对照顺序是否和要求接受的参数一致
sammitan 2003-08-04
  • 打赏
  • 举报
回复
大蝦好:
多次承蒙指教感謝

我在SQL SERVER中建立一個存儲過程如下:

CREATE PROCEDURE dbo.insertdata
@aa nvarchar(15),
@bb datetime,
@cc int

AS
insert student (id, da, score) values (@aa, @bb, @cc)
GO

我在中的調用程式:

handle=sqlconnect('storesource')
if sqlexec(handle, "exec insertdata ?gg, ?ff, ?n")>0
messagebox('input succefully')
endif

其中, 同server的連接正常, gg代表學號,ff是日期, n是學分, 運行后總是無法insert

到服務器表格不知為什麼?

流星尔 2003-08-04
  • 打赏
  • 举报
回复
如何开始一个远程事务
事务它包含一个可回滚的操作段。在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")
流星尔 2003-08-04
  • 打赏
  • 举报
回复
顺便提一下,表缓冲必须有明确的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")&&调用存储过程,不需要返回光标,取消第三个参数
流星尔 2003-08-04
  • 打赏
  • 举报
回复
设置本地表可更新服务器表

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)&&设置表缓冲
newfang 2003-08-04
  • 打赏
  • 举报
回复
斑竹,你简直是俺的偶像啦…… 收藏!!!
流星尔 2003-08-04
  • 打赏
  • 举报
回复
这时brow得到的cursor你会发现,虽然修改了表中的数据,但服务器上并没有被更新.
这是因为spt得到的光标默认是可写但不可更新的。
fj_jiangqi 2003-08-04
  • 打赏
  • 举报
回复
啊……………………
恭喜楼主,在楼顶看了你的名字啦……
祝福!!!
-------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
流星尔 2003-08-04
  • 打赏
  • 举报
回复
当然也可以想存储过程传递参数查询
仍然以刚才的例子,查询不同性别的员工
在服务器上建立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
流星尔 2003-08-04
  • 打赏
  • 举报
回复
2、如何向服务器取数据
如向服务器表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

fj_jiangqi 2003-08-04
  • 打赏
  • 举报
回复
好东东,收藏……
-------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
流星尔 2003-08-04
  • 打赏
  • 举报
回复
2、如何向服务器取数据
在第一步建立和服务器数据库的连接,并取得连接句柄nhandle后
sqlexec(jb,"select * from tablename","cursorname")
加载更多回复(2)

2,749

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧