VFP操作SQL数据库

现在用SPT方式比较灵活吧,不过我也才刚刚接触,看过些示例自己没真正去实践过一整套的完整操作。下面的一些说明和示例对初学SPT应该有点用的:

SPT 起跳

熟悉 Fox 的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Through) 技术控制远程异构数据库。这些技术其实是 VFP 对 ODBC 的 API 的封装,所以对于用户来说访问远程数据库就像操作传统的DBF一样简单。关于这两种技术的使用,完全可以洋洋洒洒地写下一本书,鉴于本文主题及篇幅,这里仅枚举 SPT 技术访问远程数据的应用。

SPT与远程视图

很多人搞不懂有了远程视图这样直观、简单的工具,为什么还需要 SPT 呢?确实 SPT 较远程视图难以掌握,但细细体会你会发现:远程视图其实是对 SPT 的可视化工具!SPT 较远程视图更具威力,远程视图提供的功能只是 SPT 的一个子集。仔细探索两者优劣,我们发现:

SPT 的优势:

1. 一次得到多个Cursor
2. 执行除 Select 以外的其他 SQL 语句,如 Insert、Update、Delete等
3. 执行远程数据库的存储过程
4. 执行远程数据库的特殊函数、命令
5. 事务管理

SPT 的劣势:

1. 没有图形用户界面
2. 必须人工维护连接
3. 得到的Cursor默认是"可读写"Cursor,要使它成为"可更新"Cursor必须经过设定


下面就顺着我们对 SPT 的认识,来浏览一下这种伟大的工具吧!(注意:本文所有例程均使用 SQL Server的NorthWind 数据库演示)

管理连接:

建立连接:

(注意:本文所有示例代码若用到连接的,默认采用"建立连接"代码中产生的连接句柄"con")

WAIT ' 连接到 SQL Server 上去 ' NOWAIT NOCLEAR WINDOW
SQLSETPROP(0,"DispLogin" ,3) && 设置环境为:"从不显示 ODBC 登陆对话框"
con=SQLSTRINGCONNECT("driver=SQLServer;Server=BOE;Uid=sa;pwd=;database=northwind")
*假定 SQL Server 服务器名为 BOE, 用户 ID 是sa, 口令是空串
*如果你的 SQL Server 的服务器名, 用户 ID, 口令与上不同,请修改以上代码中的相关部分以符合你系统中的设置
WAIT clear
IF con<=0
MESSAGEBOX(' 连接失败 ',64,' 连接到 SQL Server 上去 ')
ELSE
MESSAGEBOX(' 连接成功 ',64,' 连接到 SQL Server 上去 ')
ENDIF

断开连接:

SQLDISCONNECT(con)

一次得到多个Cursor

我们可以用一次 SPT 传回多个Cursor,如下:

cSQL="SELECT * FROM EMPLOYEES"+CHR(10)+"SELECT * FROM CUSTOMERS"+CHR(10)+"SELECT * FROM PRODUCTS"
?SQLEXEC(con,cSQL,"TEMP")

SQLEXEC( ) 的返回值表示Cursor的数量,这里返回 3 。这三个Cursor分别以: TEMP,TEMP1,TEMP2 命名。

执行除 SQL-Select 以外的 SQL 语句

cSQL="IF EXISTS(SELECT * FROM CUSTOMERS WHERE CUSTOMERID='TEST')"
cSQL=cSQL+" DELETE FROM CUSTOMERS WHERE CUSTOMERID='TEST'"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('TEST',' 这是一个测试! ')"
IF SQLEXEC(CON,cSQL)<=0
MESSAGEBOX(' 执行失败 ',64,' 发送语句到 SQL Server 上去 ')
ELSE
MESSAGEBOX(' 执行成功 ',64,' 发送语句到 SQL Server 上去 ')
ENDIF

行文至此,也许有朋友会问:如果 SQL 语句中 CUSTOMERID 是一个变量怎么办呢?有两个常用的解决方案:

拼接字符串

CUSTID='TEST'
cSQL="IF EXISTS(SELECT * FROM CUSTOMERS WHERE CUSTOMERID='"+CUSTID+"')"
cSQL=cSQL+" DELETE FROM CUSTOMERS WHERE CUSTOMERID='"+CUSTID+"'"
cSQL=cSQL+" ELSE INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('"+CUSTID+"',' 这是一个测试! ')"
?SQLEXEC(CON,cSQL)

SPT 标准变量传递法

CUSTID='TEST'
cSQL="IF EXISTS(SELECT * FROM CUSTOMERS WHERE CUSTOMERID=?CUSTID)"
cSQL=cSQL+" DELETE FROM CUSTOMERS WHERE CUSTOMERID=?CUSTID"
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='VINET'
?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 在这方面的 内容很广泛,寥寥千言当然不能尽言,有兴趣的朋友可以去访问www.boeworks.com,以便查阅更多的 内容。OK,希望有机会与大家一起讨论这方面的问题。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值