D"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES(?CUSTID,’ 这是一个测试! ’)"
SQLEXEC(CON,cSQL)
执行远程数据库的存储过程
存储过程的好处自是不必多言,下面就让我们看看怎样用 SPT 调用远程数据库的存储过程。下面我们演示的是 NorthWind 数据库中的存储过程" CustOrderHist ",它的作用是返回指定客户关于产品的消费数量合计。据我所知,这里有两种书写格式供大家选择:
使用 T-SQL 的写法:
CUSTID=’VINET’
SQLEXEC(CON,’EXEC CustOrderHist ?CUSTID’,’TEMP1’)
使用 ODBC 的写法:
CUSTID=’VI
NET’
SQLEXEC(CON,’{CALL CustOrderHist(?CUSTID)}’,’TEMP2’)
存储过程常常会需要返回一些变量,通用的方法就是使用输出参数。在
演示之前,我们先用
特殊函数和命令
如果在 SQL Server 中你有足够的权限,通过 SPT 使用远程数据库的特殊函数和命令,你可以完全控制 SQL Server ,这里我们就演示“怎样取得数据库服务器的时间”:
SQLEXEC(con,"select getdate() as serverdatetime","temp1")
temp1.serverdatetime
USE IN ("temp1")
事务管理
在一些复杂的应用中,往往会有一项操作影响几个表的情况。就客户端来说,发送到远程数据库的数据变动可能来源很多:表缓冲的多行记
录的变动,行缓冲的单行记录变化,以及前文我们演示的直接用 SQL 语句传递的数据维护,林林总总……怎样把这些更新行为控制在一个事务中呢!要么一起成功,要么一起回滚。
cSQL="DELETE FROM CUSTOMERSswheresCUSTOMERID=’BLAUS’"+CHR(10)
cSQL=cSQL+"INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES(’TEST1’,’ 这是一个测试! ’)"
SQLSETPROP(CON,"Transactions" ,2)&;&;&;&; 开始一个事务
IRETURN=SQLEXEC(CON,cSQL)
IF IRETURN=1
SQLCOMMIT(CON)&;&;&;&; 事务交付
ELSE
SQLROLLBACK(CON)&;&;&;&; 事务回滚
ENDIF
SQLSETPROP(CON,"Transactions" ,1)&;&;&;&; 重新回到自动事务处理状态
&;&;&;&;就本例而言,“DELETE FROM CUSTOMERSswheres CUSTOMERID=’BLAUS’”总是不能执行的,SQL Server会返回出错揭示:
&;&;&;&;DELETE statement conflicted with COLUMN REFERENCE constraint ’FK_Orders_Customers’.
&;&;&;&;The conflict occurred in database ’Northwind’, table ’Orders’, column ’CustomerID’.
&;&;&;&;所以这笔事务总是被回滚的!!
从例程中可以看到,我们开启的事务其实是针对“连接”的,也就是说通过该“连接”的所有数据更新都包含于事务中,直到事务被回滚或交付。
SQLSETPROP(CON,"Transactions" ,2 ), 其实是开启了人工事务处理,也就是说必须由用户明确地给出交付或者回滚指令,事务才会结束。所以笔者以为:完成一笔事务以后,应执行 SQLSETPROP(CON,"Transactions" ,1 ) 将“连接”的事务模式设为默认的“自动”,这样可以防止用户陷入未知的事务中去。
SPT的基本操作还不止这些,以后我们还会为读者朋友介绍其他一些基本操作。如果朋友们能掌握这些基本操作,就能编写不错的 C/S
程序了。虽然本文是用 SQL Server 作为远程数据库,但是如果你使用 DB2和Oracle等,在 VFP 中也可以进行同样的处理。
本文开始已提到 VFP 在这方面的内容很广泛,寥寥千言当然不能尽言,有兴趣的朋友可以去访问boeworks,以便查阅更多的内容。OK,希望有机会与大家一起讨论这方面的
问题。