版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、vfp远程视图与spt应用详解-远程视图(Remote Views)与SPT(SQL pass through)是vfp为开发Client/Server程序提供的两个内置的解决方案,如果您更深入的应用vfp,这两部分的内容是必须掌握的。由于内容比较多,文章分成若干篇几次发完。但个人认为,远程视图与spt又是不可分割的整体,虽然spt应用得比较多,但若对远程视图没有比较深入的了解,我想你也不见得能用好spt。因此做了这个目录,希望您能从远程视图开始,逐步了解这两个伟大的开发工具的使用。一、SPT详解1二、用vfp与sql server构建Client/Server应用程序(SPT)(1)7三、用
2、vfp与sql server构建Client/Server应用程序(SPT)(2)22四、用vfp与sql server构建Client/Server应用程序(远程视图)(1)25五、用vfp与sql server构建Client/Server应用程序(远程视图)(2)30六、用vfp与sql server构建Client/Server应用程序(远程视图)(3)34七、用vfp与sql server构建Client/Server应用程序(远程视图)(4)39八、用vfp与sql server构建Client/Server应用程序(远程视图)(5)48foxpro for graph对象全接触(
3、1)52foxpro for graph对象全接触(2)55用vfp动态生成数据网页(一)60用vfp动态生成数据网页(二)64一、SPT详解 -说在前面熟悉 Fox 的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Through) 技术控制远程异构数据库。这些技术其实是 VFP 对 ODBC 的 API 的封装,所以对于用户来说访问远程数据库就像操作传统的DBF一样简单。关于这两种技术的使用,完全可以洋洋洒洒地写下一本书,鉴于本文主题及篇幅,这里仅枚举 SPT 技术访问远程数据的应用。SPT与远程视图很多人搞不懂有了远程视图这样直观
4、、简单的工具,为什么还需要 SPT 呢?确实 SPT 较远程视图难以掌握,但细细体会你会发现:远程视图其实是对 SPT 的可视化工具!SPT 较远程视图更具威力,远程视图提供的功能只是 SPT 的一个子集。仔细探索两者优劣,我们发现:SPT 的优势:1. 一次得到多个Cursor2. 执行除 Select 以外的其他 SQL 语句,如 Insert、Update、Delete等3. 执行远程数据库的存储过程 4. 执行远程数据库的特殊函数、命令 5. 事务管理SPT 的劣势:1. 没有图形用户界面 2. 必须人工维护连接3. 得到的Cursor默认是"可读写"Cursor,
5、要使它成为"可更新"Cursor必须经过设定下面就顺着我们对 SPT 的认识,来浏览一下这种伟大的工具吧!(注意:本文所有例程均使用 SQL Server的NorthWind 数据库演示)管理连接:建立连接:(注意:本文所有示例代码若用到连接的,默认采用"建立连接"代码中产生的连接句柄"con")WAIT ' 连接到 SQL Server 上去 ' NOWAIT NOCLEAR WINDOW SQLSETPROP(0,"DispLogin" ,3) && 设置环境为:"从不
6、显示 ODBC 登陆对话框" con=SQLSTRINGCONNECT("driver=SQL Server;Server=BOE;Uid=sa;pwd=;database=northwind") *假定 SQL Server 服务器名为 BOE, 用户 ID 是sa, 口令是空串*如果你的 SQL Server 的服务器名, 用户 ID, 口令与上不同,请修改以上代码中的相关部分以符合你系统中的设置WAIT clear IF con<=0 MESSAGEBOX(' 连接失败 ',64,' 连接到 SQL Server 上去 '
7、;) 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"
8、;) 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(CU
9、STOMERID,COMPANYNAME) VALUES('TEST',' 这是一个测试! ')" IF SQLEXEC(CON,cSQL)<=0 MESSAGEBOX(' 执行失败 ',64,' 发送语句到 SQL Server 上去 ') ELSE MESSAGEBOX(' 执行成功 ',64,' 发送语句到 SQL Server 上去 ') ENDIF 行文至此,也许有朋友会问:如果 SQL 语句中 CUSTOMERID 是一个变量怎么办呢?有两个常用的解决方案:拼接字符串 C
10、USTID='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('"+CUST
11、ID+"',' 这是一个测试! ')" ?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,COMPANYN
12、AME) VALUES(?CUSTID,' 这是一个测试! ')" ?SQLEXEC(CON,cSQL)执行远程数据库的存储过程 存储过程的好处自是不必多言,下面就让我们看看怎样用 SPT 调用远程数据库的存储过程。下面我们演示的是 NorthWind 数据库中的存储过程" CustOrderHist ",它的作用是返回指定客户关于产品的消费数量合计。据我所知,这里有两种书写格式供大家选择:使用 T-SQL 的写法: CUSTID='VINET' ?SQLEXEC(CON,'EXEC CustOrderHist ?CUSTI
13、D','TEMP1') 使用 ODBC 的写法: CUSTID='VINET' ?SQLEXEC(CON,'CALL CustOrderHist(?CUSTID)','TEMP2')存储过程常常会需要返回一些变量,通用的方法就是使用输出参数。在演示之前,我们先用 SPT 在 SQL Server 建立一个包含输入、输出参数的存储过程。 cSQL="IF EXISTS(select * from sysobjects where id=object_id('MY_PROC') and OBJECTP
14、ROPERTY(id,'IsProcedure')=1)"cSQL=cSQL+" drop procedure MY_PROC " &&如果存储过程My_proc已经存在,就删除它?SQLEXEC(con,cSQL)cSQL="CREATE PROCEDURE MY_PROC EmployeeID int,Desc varchar(100) output as /* 只支持寻找直接下属 */"+chr(10) cSQL=cSQL+" DECLARE ROW INT"+chr(10) cSQL=
15、cSQL+" SELECT * FROM EMPLOYEES WHERE REPORTSTO=EMPLOYEEID"+chr(10) cSQL=cSQL+" SELECT ROW=ROWCOUNT"+chr(10) cSQL=cSQL+" IF ROW>0"+chr(10) cSQL=cSQL+" SELECT Desc=' 找到了 '+CAST(ROW AS VARCHAR(4) +' 位下属 '"+chr(10) cSQL=cSQL+" ELSE SELECT D
16、esc=' 这是一位普通员工 '" ?SQLEXEC(con,cSQL) 使用 T-SQL 的写法: EMPID=2 DESCRIPTION="" ?SQLEXEC(CON,'EXEC MY_PROC ?EMPID,?DESCRIPTION','TEMP1') ?DESCRIPTION 使用 ODBC 的写法: EMPID=2 DESCRIPTION="" ?SQLEXEC(CON,'CALL MY_PROC(?EMPID,?DESCRIPTION)','TEMP2'
17、;) ?DESCRIPTION 执行远程数据库的特殊函数、命令如果在 SQL Server 中你有足够的权限,通过 SPT 你可以完全控制 SQL Server ,这里我们演示"怎样取得数据库服务器的时间":?SQLEXEC(con,"select getdate() as serverdatetime","temp1") ?temp1.serverdatetime USE IN ("temp1") 事务管理 在一些复杂的应用中,往往会有一项操作影响好几个表的情况。就客户端来说,发送到远程数据库的数据变动可能来源很
18、多:表缓冲的多行记录的变动,行缓冲的单行记录变化,以及前文我们演示的直接用 SQL 语句传递的数据维护,林林总总怎样把这些更新行为控制在一个事务中要么-一起成功,要么一起回滚。cSQL="DELETE FROM CUSTOMERS WHERE CUSTOMERID='BLAUS'"+CHR(10) cSQL=cSQL+"INSERT CUSTOMERS(CUSTOMERID,COMPANYNAME) VALUES('TEST1',' 这是一个测试! ')" SQLSETPROP(CON,"Tran
19、sactions" ,2)&& 开始一个事务 IRETURN=SQLEXEC(CON,cSQL) IF IRETURN=1 SQLCOMMIT(CON)&& 事务交付 ELSE SQLROLLBACK(CON)&& 事务回滚 ENDIF SQLSETPROP(CON,"Transactions" ,1)&& 重新回到自动事务处理状态 &&就本例而言,"DELETE FROM CUSTOMERS WHERE CUSTOMERID='BLAUS'"总是不
20、能执行的,SQL Server会返回错误:&&DELETE statement conflicted with COLUMN REFERENCE constraint 'FK_Orders_Customers'. &&The conflict occurred in database 'Northwind', table 'Orders', column 'CustomerID'.&&所以这笔事务总是被回滚的!从例程中我们看到,我们开启的事务其实是针对"连接"的,
21、也就是说通过该"连接"的所有数据更新都包含于事务中,直到事务被回滚或交付。 SQLSETPROP(CON,"Transactions" ,2 ), 其实是开启了人工事务处理,也就是说必须由用户明确的给出交付或者回滚指令,事务才会结束。所以笔者以为:完成一笔事务以后,应执行 SQLSETPROP(CON,"Transactions" ,1 ) 将"连接"的事务模式设为默认的"自动",这样可以防止用户陷入未知的事务中去。 设为可更新到目前为止,我们已经演示了 6 个 SPT 专题了,除了第一个&qu
22、ot;连接管理"在远程视图中能够实现之外,其余的远程视图都无法实现。下面我们要讨论一下怎样把 SPT 传回的结果集合设为"可更新",总的来说远程视图提供的就是这个功能。 在默认状况下, SPT 从远程数据库得到的Cursor是"可读写"的,即:可以对它进行" Select 、 Update 、 Insert 、 Delete "的操作,但数据的变化不会反映到数据源。"可更新"Cursor的特色就是可以直接将客户端的数据变动,自动生成一系列 SQL 描述更新远程数据库。 实现"可读写"C
23、ursor到"可更新"Cursor必须经历以下五步的设置: 1. CURSORSETPROP("TABLES", 数据源表名 , 可更新Cursor名 ) 此步骤设定的是数据源里(SQL Server)待更新的表名,如果涉及多个表就这样写: CURSORSETPROP("TABLES","T1,T2","MyCursor") 。2. CURSORSETPROP("KEYFIELDLIST", 关键字段 , 可更新Cursor名 )此步骤是设定关键字段的,这个关键字段是可更新C
24、ursor的字段,而不是数据源里的字段。 3. CURSORSETPROP("UPDATABLEFIELDLIST", 可更新字段列表 , 可更新Cursor名 ) 此步骤设定的是在可更新Cursor里哪些字段的变动要被反映到数据源,即哪些字段时可更新的。 4. CURSORSETPROP("UPDATENAMELIST", 前后段字段对应关系列表 , 可更新Cursor名 ) 此步骤设定数据源字段与可更新Cursor字段的对应关系。 5. CURSORSETPROP("SENDUPDATES",.T., 可更新Cursor名 ) 这
25、个步骤是打开 SQL 发送开关,最关键的一步。 为便于大家理解,现将以上五步实例化:例一:SQLEXEC(con,"select categoryid as id ,categoryname,description from categories","mycursor") SELECT mycursor CURSORSETPROP("Tables","categories","mycursor") CURSORSETPROP("KeyFieldList","id&q
26、uot;,"mycursor") CURSORSETPROP("UpdatableFieldList" ,"id,categoryname,description","mycursor") CURSORSETPROP("UpdateNameList","id categories.categoryid,categoryname categories.categoryname,"+; "description categories.description",
27、"mycursor") CURSORSETPROP("SendUpdates" ,.t.,"mycursor") 例二:SQLEXEC(con,"select ductid,ductname,a.unitprice,b.categoryid,b.categoryname,c.supplierid,"+; "panyname as suppliername,c.contactname"+; " from (products a inner join categorie
28、s b on a.categoryid=b.categoryid)"+; " inner join suppliers c on a.supplierid=c.supplierid","mycursor") SELECT mycursor CURSORSETPROP("Tables","products,categories,suppliers","mycursor") CURSORSETPROP("KeyFieldList","productid,cat
29、egoryid,supplierid","mycursor") CURSORSETPROP("UpdatableFieldList",+; "productid,productname,unitprice,categoryid,categoryname,supplierid,suppliername,contactname","mycursor") CURSORSETPROP("UpdateNameList","productid ductid,pro
30、ductname "+; "ductname,unitprice products.unitprice,"+; "categoryid categories.categoryid,categoryname categories.categoryname,"+; "supplierid suppliers.supplierid,suppliername panyname,contactname suppliers.contactname","mycursor") CURSORSETP
31、ROP("SendUpdates" ,.t.,"mycursor")行笔匆匆,终于把我认识的 SPT 基本操作写完了,掌握这些,已能编写不错的 C/S 程序。虽然,本文是用 SQL Server 作为远程数据库,但是如果你使用 DB2 、 Oracle ,在 VFP 中也是一样处理。本文来自编程入门网:二、用vfp与sql server构建Client/Server应用程序(SPT)(1) -一些题外话 最近有一种好的现象越来越多的Visual FoxPro用户开始注意到Client/Server应用程序的重要性,他们开始安装SQL Server了。作为
32、开发人员,我们没有必要深入认识SQL Server的种种(我个人以为那是数据库管理员DBA的事情),我们要解决的是怎样使Visual FoxPro与SQL Server在一起顺利的运行,怎样发挥两者的优越特性。“远程视图”一章已经涉及到了许多深层次的问题,但遗憾的是(可能是文章太过枯燥)很少有人关注它!笔者到现在还是认为,“远程视图”一文绝对是目前网络上能得到的最好的简体中文学习资料,没有哪篇文章会为你深入介绍“更新冲突发生的原理”,没有哪篇文章会为你讲解“Visual FoxPro发送更新到SQL Server 的原理”,没有哪篇文章会为你讲解“各种连接属性的意义”在国内众多Visual F
33、oxPro图书中,我最喜欢的作者是台湾的章立民先生。我个人以为Visual FoxPro的章立民、Delphi的李维、Visual Basic的王国荣是那种多数读者看到是他们写的作品就应该买的那类作者。三位大家的书我都有拜读,窃以为:文采最棒的是章立民先生,名气最小的也是章立民先生(也许是因为Visual FoxPro的关系)。中国铁道出版社为国内的Visual FoxPro事业做了一件好事在99年前后出版了章立民先生的四册图书,分别是:Visual FoxPro 6.X 中文版程序设计教学指南、Visual FoxPro 6.X 中文版程序设计基础加强、Visual FoxPro 6.X 中
34、文版程序设计问题集、Visual Foxpro 6.X 中文版程序设计应用实务。除了教学指南外,其余三本都是进阶应用的好书,但很奇怪的是他们在市场上销售的并不理想,直到今年上半年在上海书市中还能觅到,相反的一些粗制滥造的东西却是卖得火爆,真是咄咄怪事!我不认识章立民先生,与中国铁道出版社更无关系,但我愿意为他们做广告,如果章立民能为Visual FoxPro 7写出更好的东西,我们将感激不尽,也希望国内出版社积极参与引进!本文在写作上参考了Visual Foxpro 6.X 中文版程序设计应用实务的内容,但绝对不是抄袭,大家有兴趣可以买一本读上一读。为什么要引入SPT的概念我们已经讲解了“远程
35、视图”,您也许已经发现了远程视图的不足,是的远程视图的缺陷正是SPT的优势所在:执行除Select以外的其他的SQL语句,如Insert 及Update等 执行后端数据库的存储过程 执行后端数据库的特殊的函数、命令 一次得到多个数据集合这些都是我们在系统开发时要遇到的实现问题,Visual FoxPro 小组注意到了,于是提出了SPT的概念。SPT是SQL Pass Through的简写,它与远程视图在一起共同组成Visual FoxPro远程数据访问体系,利用它们你就可以开发完整的ClientServer构架的系统了!与“远程视图”相比,SPT技术也有以下缺陷:没有图形用户界面 必须人工维护
36、连接 数据集合是“可读写光标”,要使它成为“可更新光标”必须进行设定 从我的经验来看待“远程视图”与SPT,我以为两者是Visual FoxPro远程数据访问体系的双臂,相辅相成。不用SPT,系统就会变得弱智、愚笨;不用远程视图,系统开发会变得缓慢、繁琐。我以为,“远程视图”是组件化的SPT,是微软公司对SPT部分功能的图像化封装,所以它显得更有生产效率,同时由于系统作得多了,功能也就弱了,“远程视图”能做得就是那些事情从数据源读取一个结果集,在客户端对它维护,并自动将变动结果更新到数据源。然而作为系统开发,我们会在实践中遇到林林总总、奇奇怪怪的需求,只有“远程视图”独立担当显然是不行的,所以
37、SPT的出现有它的必然性。在其他的远程数据处理组件中也有类似的概念,例如ADO中的RecordSet相当于Visual FoxPro的远程视图,Command相当于Visual FoxPro的SPT。13个SPT函数Visual FoxPro 中内置了13个以SQL开头的函数,我们把它们称为SPT函数。就是这13个函数完成了Visual FoxPro的所有的SQL Pass Though功能。从功能上看,我们可以把它们分成五个部分:连接函数连接建立函数:SqlConnect(),SqlStringConnect()连接的断开函数:SqlDisconnect()核心的执行函数SQL语句传输及执行
38、函数:SqlExec(),SqlPrapare()批次模式下更多数据集的取得函数:SqlMoreResults()异步模式下撤销正在执行的SPT的函数:SqlCancel()事务处理函数SqlCommit(),SqlRollBack()连接通道属性函数SqlGetProp(),SqlSetProp()数据源的信息截取函数SqlTables(),SqlColumns()连接到SQL Server连接SqlConnect()的两种用法一般来说SqlConnect有两种用法:直接调用操作系统里的用户型或系统型DNS;使用当前数据库DBC的连接对象。如果已经在操作系统中制作了一个名为LocalServ
39、er的系统型DNS,在命令窗口中我们就可以直接键入:SQLCONNECT("localserver","sa","")如果当前数据库中存在连接对象,我们就可以这样调用它:SQLCONNECT("NorthWind")SqlStringConnect()函数的用法在用了SqlConnect以后,大家也许会发现不太自由,能不能及时动态建立连接呢?可以的,用SqlStringConnect()就可以了:SQLSTRINGCONNECT("driver=SQL Server;Server=See-you;Uid=
40、sa;pwd=;database=northwind")我们解释一下参数字符串的意义,driver指明了使用哪一个ODBC驱动程序,这里是SQL Server;Server是指SQL Server的服务器名称,我的服务器叫:See-You;UID是在SQL Server的用户名称,这里使用SA;PWD是用户口令,这里为空值;最后我们指定了要连接的数据库的名字,这次我们仍然使用NorthWind数据库。所有这些条件组成了一个字符串,各条件用分号分割,我的实验表明对这大小写的要求不高,当然不包括用户口令和用户名。关于连接的两大问题连接建立起来很简单,但尚有问题要解决:怎么判断连接是否成功
41、?怎么屏蔽SQL Server的登陆对话框?第一个问题很好解决,只要SqlConnect()或是SqlStringConnect()返回正整数(>0的数)就表示连接成功,得到的正整数很重要就是连接句柄!STORE SQLCONNECT('LocalServer', 'sa','错误密码') TO gnConnHandleIF gnConnHandle <= 0= MESSAGEBOX('连接错误', 16, '连接到SQL Server')ELSE= MESSAGEBOX('连接成功',
42、 48, '连接到SQL Server')ENDIF在有些时候,连接发生错误会弹出以下两个提示框(有时出现前一个、有时出现后一个,有时连续出现):连接错误提示SQL Server的登录提示这是一个让人迷惑的的问题,我以为:第一个“连接错误提示”是限于Visual FoxPro或ODBC的层次,也就是说与SQL Server无关,这种错误的出现往往是找不到SQL Server服务器之类的问题,如以下的语句:SQLSTRINGCONNECT("driver=SQL Server;Server=See-y1ou;Uid=sa;pwd=;database=northwind&
43、quot;)这是为了让用户更正连接信息的,但是在实际开发中没有哪个程序员希望此对话框暴露在用户面前。如果我们使用的连接是DBC的连接对象,问题就比较好解决,因为在建立连接时我们可以设定连接对话框的出现规律:同样的我们可以通过命令来控制“显示 ODBC 登录提示”:DBSETPROP("connect1","CONNECTION" ,"DISPLOGIN" ,1) &&发生连接错误时弹出DBSETPROP("connect1","CONNECTION" ,"DISPLOG
44、IN" ,2) &&任何时候总是误时弹出DBSETPROP("connect1","CONNECTION" ,"DISPLOGIN" ,3) &&发任何时候都不弹出但是当我们使用连接字符串、直接使用操作系统的DNS时,它们都不是Visual FoxPro的DBC中的连接对象,就不能用以上的方法控制,我们可以设定Visual FoxPro的环境:SQLSETPROP(0,"DispLogin" ,3)注意我对第一个参数赋值为0,表明设定的是对Visual FoxPro的系统环
45、境进行设定。值得注意的是,系统环境设定只是与这种即时产生连接有效,对存放在DBC中的连接对象并不起作用,根据连接对象建立的连接的有关属性还是要通过DBSETPROP()来设定。断开连接建立的连接就应该再不用时及时断开,断开连接请使用SqlDisConnect()函数。Local hConnhconn=SQLCONNECT("NorthWind")?SQLDISCONNECT(hconn)/返回1表示连接断开成功这里有三个问题提请大家注意。第一,如果hconn是一个有效的连接句柄,对它执行SqlDisConn()函数会有这样的结果,成功返回1,其他表示断开操作失败;第二:如果
46、hconn不是一个有效的连接句柄,Visual FoxPro将触发一个错误,错误代号为1466,怎样判断某个连接句柄是不是有效的方法,我们在后文介绍;第三,如果想一下子断开所有的连接,您可以使用这样的方法:SQLDISCONNECT(0)从后端得到数据集得到一个数据集SQLEXEC(nConnectionHandle, cSQLCommand, cCursorName)先来解释一下SQLEXEC()函数:参数nConnectionHandle表示连接句柄;参数cSQLCommand表示要传送的语句,注意此语句一定是数据源认得的语句,而不是Visual FoxPro的语句。这一点从SQL Pas
47、s Though这个名字上就能看得出了,顾名思义:Visual FoxPro只不过是是将别人的语言传送给别人,这一点在SQLEXEC()函数体现的特别突出;参数cCursorName表示得到的结果集的名字,如果省略,返回的结果集将以Sqlresult命名。如果返回1表示,执行成功;如果返回0表示正在执行;如果返回负数表示执行失败。如果我们希望得到NorthWind数据库中的Employees表的数据,就可以执行以下命令:SQLEXEC(hconn,"SELECT * FROM EMPLOYEES","MyCursor")Browse判断连接有效性这是一个
48、非常实际的问题,我们建立了一条连接以后,怎样知道Visual FoxPro与SQL Server的通信是正常的,机连接是确实有效的,只有一种方法应用这条连接,可以这样:?SQLEXEC(hconn,"")&&一个空的命令发送,返回1的话证明连接可用!大型语句的传递技巧如果想得到一个更为复杂的结果集合,我们可以传送依据大型的SQL-Select描述。这里有一些经验送给大家:如果传送的语句太大(大约是超过256个字符,其实没有必要去计数只要你觉得语句很大时就应该考虑我的建议,不然您就没有办法传送大型的语句),您直接把要传送的语句放入SQLEXEC()中,Visu
49、al FoxPro就会报错,说无法认得此语句,于是大家就又多了诽谤Visual FoxPro的一条把柄!(根据我的研究,在Delphi中也有此问题)解决之道是:把长长的语句先放在一个变量中,再将此变量作为参数赋给SQLEXEC()函数。 关于分隔符的使用技巧,Visual FoxPro中分隔字符串使用三种符号:双引号、单引号、方括号。在配置要传送的语句时一定要用双引号作为字符串的分隔符,其他的两个符号应另作他用。以上的建议绝对经典,以下我们就用实例来说明:在SQL Server中要得到详细销售情况的SQLSelect语句如下(详细的知识见本人撰写的SELECT-SQL 周周谈一文):SELEC
50、T ORDERS.SHIPNAME,ORDERS.SHIPADDRESS,ORDERS.SHIPCITY,ORDERS.SHIPREGION,ORDERS.SHIPPOSTALCODE,ORDERS.SHIPCOUNTRY,ORDERS.CUSTOMERID,CUSTOMERS.COMPANYNAME AS CUSTOMERNAM,EMPLOYEES.FIRSTNAME+' '+EMPLOYEES.LASTNAME AS SALESPERSON,ORDERS.ORDERID,ORDERS.ORDERDATE,ORDERS.REQUIREDDATE,ORDERS.SHIPPEDD
51、ATE,SHIPPERS.COMPANYNAME AS SHIPPERNAME,ORDER DETAILS.PRODUCTID,PRODUCTS.PRODUCTNAME,ORDER DETAILS.UNITPRICE,ORDER DETAILS.QUANTITY,ORDER DETAILS.DISCOUNT,ORDER DETAILS.UNITPRICE*ORDER DETAILS.QUANTITY*(1-ORDER DETAILS.DISCOUNT) AS EXTENDEDPRICE, ORDERS.FREIGHTFROM (EMPLOYEES INNER JOIN ORDERS ON EM
52、PLOYEES.EMPLOYEEID=ORDERS.EMPLOYEEID) INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERID=CUSTOMERS.CUSTOMERID)INNER JOIN SHIPPERS ON ORDERS.SHIPVIA=SHIPPERS.SHIPPERID)INNER JOIN ORDER DETAILS ON ORDERS.ORDERID=ORDER DETAILS.ORDERID)INNER JOIN PRODUCTS ON ORDER DETAILS.PRODUCTID=PRODUCTS.PRODUCTID这是一句12行,不计空格
53、864个字符的大型语句,现在要通过Visual FoxPro的SQLEXEC()函数传送:local csq&&配置待传送的语句csql=csql+"SELECT ORDERS.SHIPNAME,ORDERS.SHIPADDRESS,ORDERS.SHIPCITY,ORDERS.SHIPREGION,"csql=csql+"ORDERS.SHIPPOSTALCODE,ORDERS.SHIPCOUNTRY,ORDERS.CUSTOMERID,"csql=csql+"CUSTOMERS.COMPANYNAME AS CUSTOMER
54、NAM,"csql=csql+"EMPLOYEES.FIRSTNAME+' '+EMPLOYEES.LASTNAME AS SALESPERSON,ORDERS.ORDERID,ORDERS.ORDERDATE,"csql=csql+"ORDERS.REQUIREDDATE,ORDERS.SHIPPEDDATE,SHIPPERS.COMPANYNAME AS SHIPPERNAME,"csql=csql+"ORDER DETAILS.PRODUCTID,PRODUCTS.PRODUCTNAME,ORDER DETAIL
55、S.UNITPRICE,"csql=csql+"ORDER DETAILS.QUANTITY,ORDER DETAILS.DISCOUNT,"csql=csql+"ORDER DETAILS.UNITPRICE*ORDER DETAILS.QUANTITY*(1-ORDER DETAILS.DISCOUNT) AS EXTENDEDPRICE,"csql=csql+"ORDERS.FREIGHT"csql=csql+" FROM (EMPLOYEES INNER JOIN ORDERS ON EMPLOYEES.E
56、MPLOYEEID=ORDERS.EMPLOYEEID)"csql=csql+" INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERID=CUSTOMERS.CUSTOMERID)"csql=csql+" INNER JOIN SHIPPERS ON ORDERS.SHIPVIA=SHIPPERS.SHIPPERID)"csql=csql+" INNER JOIN ORDER DETAILS ON ORDERS.ORDERID=ORDER DETAILS.ORDERID)"csql=csql+&q
57、uot; INNER JOIN PRODUCTS ON ORDER DETAILS.PRODUCTID=PRODUCTS.PRODUCTID"&&传送,得到的光标名称为默认的SqlResultSQLEXEC(hconn,csql)解释:由于语句很长,我花费了多条赋值语句才完成配置这个字符串。大家注意到了我选用双引号作为字符串分隔符,这里面是有大学问的。在SQL Server中有待空格的表名如:Order Details,当它用于SQL语句时,就必须要用方括号标示,所以如果在Visual FoxPro中如果用方括号分割字符串的话,就会有冲突!;单引号是SQL Serve
58、r中分隔字符串、日期值的符号,在Visual FoxPro中如果使用单引号分隔字符串的话,也会造成冲突,当然在以上语句中我们没有看到单引号的身影,不过我们做一个变动,大家就会感到问题的存在了!local csq&&配置待传送的语句csql=csql+"SELECT ORDERS.SHIPNAME,ORDERS.SHIPADDRESS,ORDERS.SHIPCITY,ORDERS.SHIPREGION,"csql=csql+"ORDERS.SHIPPOSTALCODE,ORDERS.SHIPCOUNTRY,ORDERS.CUSTOMERID,&quo
59、t;csql=csql+"CUSTOMERS.COMPANYNAME AS CUSTOMERNAM,"csql=csql+"EMPLOYEES.FIRSTNAME+' '+EMPLOYEES.LASTNAME AS SALESPERSON,ORDERS.ORDERID,ORDERS.ORDERDATE,"csql=csql+"ORDERS.REQUIREDDATE,ORDERS.SHIPPEDDATE,SHIPPERS.COMPANYNAME AS SHIPPERNAME,"csql=csql+"ORDER
60、DETAILS.PRODUCTID,PRODUCTS.PRODUCTNAME,ORDER DETAILS.UNITPRICE,"csql=csql+"ORDER DETAILS.QUANTITY,ORDER DETAILS.DISCOUNT,"csql=csql+"ORDER DETAILS.UNITPRICE*ORDER DETAILS.QUANTITY*(1-ORDER DETAILS.DISCOUNT) AS EXTENDEDPRICE,"csql=csql+" ORDERS.FREIGHT"csql=csql+&qu
61、ot; FROM (EMPLOYEES INNER JOIN ORDERS ON EMPLOYEES.EMPLOYEEID=ORDERS.EMPLOYEEID)"csql=csql+" INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERID=CUSTOMERS.CUSTOMERID)"csql=csql+" INNER JOIN SHIPPERS ON ORDERS.SHIPVIA=SHIPPERS.SHIPPERID)"csql=csql+" INNER JOIN ORDER DETAILS ON ORD
62、ERS.ORDERID=ORDER DETAILS.ORDERID)"csql=csql+" INNER JOIN PRODUCTS ON ORDER DETAILS.PRODUCTID=PRODUCTS.PRODUCTID"csql=csql+" WHERE ORDERS.ORDERDATE BETWEEN '1996-10-01' AND '1997-09-30'"csql=csql+" AND ORDERS.CUSTOMERID LIKE '%C%'"csql=csql+
63、" AND ORDER DETAILS.QUANTITY>50"&&传送,得到的光标名称为默认的SqlResultSQLEXEC(hconn,csql)传递变量上面一个例子充分证明了我关于字符串分隔符的经验,接着我又为大家提出了一个新课题:怎样传递变量到SQL Server中。上例中,我们为语句加入了Where字句,下面我们把其中的条件值变为变量,这样这句SQL传递才变得真正的有意义!我以为关于变量的传递有两种方法,下面逐一介绍。第一种是利用:问号+变量来传递的,这是一种常用的方法,用起来也很简单,不用担心变量的类型,ODBC会自动的转化。下面的例子中就涉及到了日期型、数值型、字符型变量,我们根本不用担心变量类型的转化,只要在前面加上问号填入语句中就行了:local csq&&要传送的变量dDate1=1996-10-01dDate2=1997-09-30cCustomerID="%C%"nQty=50&&配置待传送的语句csql=csql+"SELEC
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 酒店保安员岗位责任制度
- 2026年及未来5年市场数据中国硅酸盐水泥行业市场深度研究及投资战略规划报告
- 2026年上半年葫芦岛市教育局赴高等院校招聘教师(东北师范大学站)考试备考试题及答案解析
- 2026陕西西安经开第十九小学合同制教师招聘考试参考题库及答案解析
- 欠款清偿约定离婚协议书
- 四川职业技术学院2026年上半年公开招聘事业编制工作人员(30人)笔试备考试题及答案解析
- 2026四川眉山市丹棱县就业服务中心城镇公益性岗位安置7人笔试参考题库及答案解析
- 2026年聊城市竞技体育学校公开招聘工作人员(2人)考试参考题库及答案解析
- 水下钻井设备操作工岗前安全技能考核试卷含答案
- 连铸工岗前班组协作考核试卷含答案
- 周围血管与淋巴管疾病第九版课件
- 付款计划及承诺协议书
- 王君《我的叔叔于勒》课堂教学实录
- 中山大学教师考核实施办法
- CTQ品质管控计划表格教学课件
- 沙库巴曲缬沙坦钠说明书(诺欣妥)说明书2017
- GB/T 42449-2023系统与软件工程功能规模测量IFPUG方法
- GB/T 5781-2000六角头螺栓全螺纹C级
- 卓越绩效管理模式的解读课件
- 枇杷病虫害的防治-课件
- 疫苗及其制备技术课件
评论
0/150
提交评论