1.CLIENT/SERVER 到底是什么?
C/S属于2-TIER系统,适合于中小型应用系统。大系统一般都用3-TIER了。
打个比方单机数据库系统(比如VFP), 相当于前店后库.店里需要什么东西,得自己去库房找,库房管理也是有你自己进行. 而C/S系统下,店和库是相对独立的,有一个专门的库房管理(数据SERVER),店里需要什么,按照手续把单子给
库房管理人员,由他们去操作.
因此可以看出C/S的优点: 支持多用户; 更有效的数据管理,数据安全和可靠得多;远程使用数据.
如果你是单机使用当然没有太大必要使用C/S了.
如果用VFP本身做C/S系统, 效果不是很明显,因为VFP的数据管理功能不是很强,比如加锁解锁都需要程序来操作. 我主要说的是VFP/SQL SERVER系统.
2. SQL SERVER
SQL SERVER是微软发布的RDBMS(关系数据库管理系统), ORACLE, INFOMIX,POWERBUILD,也都是类似的系统. 他们就相当于仓库的管理系统,但功能不仅仅是数据管理. 微软的数据库产品从功能和规模由小到大排列依次是: ACCESS, VFP, SQL SERVER.
稍微大一点的系统,SQL SERVER是需要专人管理的,这就是DBA (DATABASE ADMINISTRATOR)的位置.现在北美人才市场上, DBA的工作比程序员的工作好找些. 工资比普通程序员略高, 工作稳定性也强一些.
SQL SERVER是一套大的软件系统,可以安装在专门的NT数据SERVER上,也有个人版可以安装在WIN95/98上, 主要是为了咱们这些程序员方便测试. 它的功能主要有这么几块: 数据库的管理和维护,用户/安全管理, 数据的发布/转换.
3. 用VFP/SQL SERVER做C/S系统
VFP和SQL SERVER的搭配应该是比较完美的, 但因为VB才是微软的主流产品(VB一直是微软的,FOXPRO是后来才买的,后娘生的), 所以微软从来没有大力推荐或者宣传过VFP, 而是把VFP独有的数据库技术融合到自己的其它产品里了: SQL SERVER, ODBC, OLE DB/ADO. 最近甚至把VFP从VISUAL STUDIO里独立出来了.
VFP和SQL SERVER的交流,可以通过3种方式进行:
A. 远程视图 B. ADO控件 C. SPT (SQL PASS THROUGH)
3种方式各有优缺点, 而我最偏好第3种. 远程视图和ADO都在VFP和SQL SERVER中间加了一个层次, 而这层次就相当于一个黑箱,你不清楚它们到底怎么操作数据的,只需按照它们的规则进行设置,使用
相应的命令就可以. 反正我作为程序员,喜欢清楚地知道我的程序每一步都在干什么,所以我喜欢用SPT, 也从不用向导来建立表单报表一类的.
SPT技术是通过VFP的函数SQLCONNECT()来和SQL SERVER建立连接, 然后用SQLEXEC()函数把要执行的SQL命令 送到SQL SERVER上去执行,
所有对数据的操作都是通过这些SQL命令来进行的. 每一个细节都由自己的代码来控制.
4. VFP数据的升迁
VFP的数据库,可以直接用VFP自带的升迁向导转到SQL SERVER上,但必须把所有的表都放到数据库里,自由表不能直接升迁, 而实际上升迁上去的又只是表,数据库本身不能转到SQL SERVER里. 感觉怪怪的. 也许是为了升迁索引或者关系吧.
要把VFP数据升迁到SQL SERVER上, 必须先在SQL SERVER里建立相应的数据库. SQL SERVER的管理是通过ENTERPRISE MANAGER (EM)来进行的. 通过它建立数据库, 每个数据库里可以包含 数据表,用户/用户群,视图,存储过程等等.
至于改用SQL SERVER后,原来的VFP程序是肯定需要修改的, 而且是比较大的改动.
***************
谈谈VFP和SQL SERVER搭配做C/S系统 (二) --动态设置ODBC连接
1。设置ODBC数据源
VFP和SQL SERVER的连接是通过ODBC或者OLE DB(ADO)来进行的。可以打开控制面板的ODBC数据源进行设置。但很多情况下,我们希望能在程序里动态设置数据源,一来可以不用去为每个用户的机器手动设置, 二来为了数据的安全性,使用完后,希望把ODBC数据源删掉。
下面的例子是用API函数来设置和删除ODBC数据源。
函数名字是 SQLConfigDataSource,其中第二项参数是数字(1-增加 2-修改 3-删除)
DECLARE INTEGER SQLConfigDataSource IN odbccp32 INTEGER, INTEGER, STRING, STRING
lnWindowHandle=0
lcODBCDriver='SQL Server' &&DRIVER类型
lcODBCName='SharedData' &&数据源名字
lcODBCDesc='Shared Data Source' &&数据源描述
lcODBCServer='DEVSQL' &&SQL SERVER名字
lcODBCDatabase='Shared' &&要连接的数据库名字
**先试图修改已有的ODBC,如果不存在,返回0。
lreturn=SQLConfigDataSource(lnWindowHandle, 2, lcODBCDriver, ;
'DSN=' + lcODBCName + CHR(0) ;
+ 'Description=' + lcODBCDesc + CHR(0) ;
+ 'Server=' + lcODBCServer + CHR(0) ;
+ 'Database=' + lcODBCDatabase + CHR(0))
IF lreturn=0 &&不存在
**添加新的ODBC
lreturn=SQLConfigDataSource(lnWindowHandle, 1, lcODBCDriver, ;
'DSN=' + lcODBCName + CHR(0) ;
+ 'Description=' + lcODBCDesc + CHR(0) ;
+ 'Server=' + lcODBCServer + CHR(0) ;
+ 'Database=' + lcODBCDatabase + CHR(0))
IF lreturn=0 &&失败
MessageBox('添加ODBC数据源失败',16,'BUFFER')
ENDIF
ENDIF
2。删除ODBC数据源
**用完后,可以在表单DESTROY事件里删除ODBC。 如果不想重复设置参数,可以把这些参数加到表单作为属性。
DECLARE INTEGER SQLConfigDataSource IN odbccp32 INTEGER, INTEGER, STRING, STRING
lnWindowHandle=0
lcODBCDriver='SQL Server'
lcODBCName='SharedData'
lcODBCDesc='Shared Data Source'
lcODBCServer='DEVSQL'
lcODBCDatabase='Shared'
**先修改,或者其是否存在
lreturn=SQLConfigDataSource(lnWindowHandle, ;
2, lcODBCDriver, ;
'DSN=' + lcODBCName + CHR(0) ;
+ 'Description=' + lcODBCDesc + CHR(0) ;
+ 'Server=' + lcODBCServer + CHR(0) ;
+ 'Database=' + lcODBCDatabase + CHR(0))
IF lreturn=1 &&ODBC存在,删除它
lreturn=SQLConfigDataSource(lnWindowHandle, ;
3, lcODBCDriver, ;
'DSN=' + lcODBCName + CHR(0) ;
+ 'Description=' + lcODBCDesc + CHR(0) ;
+ 'Server=' + lcODBCServer + CHR(0) ;
+ 'Database=' + lcODBCDatabase + CHR(0))
IF lreturn=0
MessageBox('删除ODBC源失败,16,'BUFFER')
ENDIF
ENDIF
**清除DLL
CLEAR DLLS
3. 从VFP连接到SQL SERVER
lnHandle=SQLConnect("SharedData","用户名”,“密码”)
If lnHandle>0 &&连接成功
**从库里获得数据(比如从EMP表里得到部门号为‘01’的职工)
lnReturn=SQLExec(lnHandle,"Select * from Emp Where cDept='01'","CursorEmp")
If lnReturn>0 &&运行成功
Browse
Else &&失败
&&出错处理
EndIf
Else &&连接失败
MessageBox("连接SQL SERVER失败”,16,“BUFFER”)
EndIf
**用完连接后,最好马上关闭,连接是很宝贵的资源,微软是按连接数收费的,而且每个连接会增加SQL SERVER的管理负担
=SQLDisconnect(lnHandle)
***************
(续) (这些贴子必须连着看)
用SPT技术更新数据时,必须通过SQL命令进行,SQL命令必须符合ANSI或者T-SQL(微软的TRANSACTION SQL),因为命令是通过VFP的SQLEXEC()函数送到SQL SERVER去执行的,语法必须遵守SQL SERVER的规则,而不是VFP的规则。不熟悉的人,最容易犯的错误就是把VFP的函数传送到SQL SERVER上执行,结果总出错。两者大部分函数都是不一样的。
比如ALLTRIM()是VFP的, SQL SERVER里是LTRIM()和RTRIM()
VFP日期以{}分界,但SQL SERVER里不认,必须用单引号.
如果SQL命令里用到VFP程序里的变量,变量前必须加问号“?”
比如,更新一个表的字段
lcLName="Zhang"
lcFName="San"
lnReturn=SQLEXEC(连接句柄,“Update Emp Set cLName=?lcName, cFName=?lcFName Where cEmpNo='733000'")
如果返回值lnReturn>0,就更新成功了
插入记录,或者逐条修改记录时,只能每次操作一条记录。
比如要把临时表TmpEmp里的记录加到SQL SERVER的EMP表里,就得用循环
Select TmpEmp
Scan
lnReturn=SQLEXEC(连接句柄,"Insert Into Emp (cEmpNo,cLName,cFName) values (?TmpEmp.cEmpNo,?cTmpEmp.cLName,?cTmpEmp.cFName)"
EndScan
*** 要得到SQL SERVER上某个表的结构,有两种办法,一是运行SQL SERVER自带的系统存储过程。一是运行一个SELECT命令。
比如要从SQL SERVER得到EMP表的结构
lnReturn=SQLEXEC(连接句柄,"Select Top 0 * From Emp","TmpEmp")
返回的结果都是临时表,是只读的,要想变成可读写的,需要做点小变化:
Select 0
Use DBF("TmpEmp") Again Alias Emp
Use In TmpEmp
现在得到的EMP临时表就是可读写的了。
*注 "Select Top 0 From Emp" 命令在VFP里是错误命令,但SQL SERVER里可以执行.
SPT和使用视图相比,优点是每一步你都清楚自己在做什么,知道为什么命令会出错。缺点是你需要多写命令,多了解SQL SERVER的语法。