第二十一章:实现客户/服务器应用程序

无论通过创建然后升迁本地原型,还是使用远程视图根据远程数据开发客户/服务器应用程序,都可以访问远程服务器数据库中存储的大量可用数据。还可以使用远程服务器上性能完善的安全性管理和事务处理能力。在用远程视图执行主要的数据管理任务时,可以使用 SQL pass-through (SPT) 技术在服务器上创建对象,运行服务器存储过程,使用当地服务器语法执行各种命令,从而大大增强应用程序的性能。

本章主要讨论如何在一个使用远程视图的应用程序中实现客户/服务器技术。如果要了解更多有关设计和创建客户/服务器应用程序的内容,请参阅第十九章“设计客户/服务器应用程序”和第二十章“升迁 Visual FoxPro 数据库”。有关创建远程视图的详细内容,请参阅第八章“创建视图”

本章内容要点:

使用 SQL pass-through 技术

客户/服务器应用程序可以使用下列方法访问服务器数据:

远程视图提供了访问和更新远程数据的最简单、最通用方法。可以利用“升迁向导”在数据库中自动创建远程视图,也可以在升迁以后使用 Visual FoxPro 来创建远程视图。有关远程视图的详细内客,请参阅第八章“创建视图”

使用 SQL pass-through 技术可以直接把 SQL 语句发送给服务器。由于这些 SQL 语句在后台服务器上运行,因而能够在很大程序上提高客户/服务器应用程序的性能。下表是远程视图和 SQL pass-through 的比较情况。

远程视图和 SQL pass-through 技术的比较

远程视图 SQL pass-through
基于 SQL SELECT 语句。 基于当地服务器的任何 SQL 语句,允许数据定义语句或者服务器存储过程的执行。
在设计时可以作为控件的数据源。 不能作为控件的数据源。
不能对数据源执行 DLL 命令。 提供了可以对数据源执行 DLL 命令的方法。
取一个结果集合。 取一个或多个结果集合。
提供内部联接管理。 需要明确的联接管理。
为更新、插入和删除提供内部的默认更新信息。 不提供默认更新信息。
隐含地执行 SQL 语句并获取数据。 需要明确地执行 SQL 语句,并控制结果获取方式。
不提供事务处理。 提供明确的事务处理。
在数据库中永久保存属性。 基于工作期属性,为 SQL pass-through 临时表提供临时属性。
在执行 SQL 时采用异步的逐步获取方式。 全面支持编程方式的异步获取。

SQL pass-through 技术与远程视图相比,具有如下优点:

SQL pass-through 查询也有缺点:

无论远程视图还是 SQL pass-through 都可以查询和更新远程数据。事实上,在许多应用程序中,远程视图和 SQL pass-through 两种技术常常同时使用。

使用 SQL pass-through 函数

在使用 SQL pass-through 连接到一个远程 ODBC 数据源时,需要首先调用 Visual FoxPro 函数 SQLCONNECT( ) 创建一个连接。然后,使用 SQL pass-through 函数把命令发送给远程数据源以执行命令。

若要使用 Visual FoxPro SQL pass-through 函数

  1. 确保系统能与数据源相连。可以使用象 ODBC Test 这样的 ODBC 工具进行检查。

  2. SQLCONNECT( )SQLSTRINGCONNECT( ) 函数建立与数据源的连接。

    例如:如果要把 Visual FoxPro 连接到 SQL Server 数据源 sqlremote 上,那么必须以系统管理员(用户标识 sa)身份注册,并给出密码 secret,即是用如下命令:

    nConnectionHandle = SQLCONNECT('sqlremote','sa','secret')
    

    注释 也可以使用 SQLCONNECT( ) 函数实现一个命名连接。

  3. 使用 Visual FoxPro SQL pass-through 函数将数据检索到 Visual FoxPro 临时表中,然后使用标准的 Visual FoxPro 命令和函数处理这些检索到的数据。

    例如,可以使用如下命令查询 authors 表并且浏览查询结果的临时表:

    ? SQLEXEC(nConnectionHandle,"select * from authors","mycursorname")
    BROWSE
    
  4. 使用 SQLDISCONNECT( ) 函数切断与数据源的连接。

Visual FoxPro SQL pass-through 函数

下表给出了 Visual FoxPro 中与远程数据源协同工作的 SQL 函数,并按所完成的任务对其分组。

任务 函数 目的
连接管理 SQLCONNECT( ) 为 SQL pass-through 操作连接一个数据源。
SQLSTRINGCONNECT( ) 使用 ODBC 联接字符串语法连接数据源。
SQLDISCONNECT( ) 断开一个对 ODBC 数据源的连接,使指定的连接句柄失效。
SQL 语句的执行和控制 SQLCANCEL( ) 在一个活动连接上,取消异步执行的 SQL 查询。
SQLEXEC( ) 在一个活动连接上执行 SQL pass-through 查询;或者返回已生成的结果集合的数目,如果 SQLEXEC( ) 仍在执行(异步处理),则返回 0 值。
SQLMORERESULTS( ) 把另一个结果集合放到临时表中。如果创建结果集合的语句仍在执行,则返回 0 值。
SQLPREPARE( ) 预编译数据源上的 SQL 语句,同时带有 Visual FoxPro 参数。也就是说,在 SQL 命令中,将所有参数保存为实际的参数表达式。
SQLCOMMIT( ) 申请提交一个事务。
SQLROLLBACK( ) 申请回滚一个事务。
数据源信息 SQLCOLUMNS( ) 将列名以及每列的信息存入一个临时表。如果成功,则返回 1;如果仍在执行,则返回 0。
SQLTABLES( ) 将数据源中的表名存入一个临时表。如果成功,则返回 1。如果仍在执行,则返回 0。
其他控制 SQLGETPROP( ) 获得活动连接的属性。
SQLSETPROP( ) 设置活动连接的属性。

如果 SET ESCAPE 设置为 ON,则 SQLEXEC( )、SQLMORERESULTS( )、SQLTABLES( ) 和 SQLCOLUMNS( ) 语句可以通过按 ESC 键以同步方式取消。此外,也可以通过发出 SQLCANCEL( ) 命令以异步方式取消这些语句。其他 SQL pass-through 语句都以同步方式工作,不能被中断。

创建结果集合

在使用 SQL pass-through 函数 SQLEXEC( )SQLMORERESULTS( ) 查询数据时,Visual FoxPro 将数据返回到一个或多个结果集合中。结果集合来源于服务器数据源中的临时表,然后成为 Visual FoxPro 中的临时表。结果集合的默认名称为 SQLRESULT。

使用 SQL pass-through 函数访问服务器存储过程

使用 Visual FoxPro SQL 的传递技术,可以建立和执行在远程服务器上的存储过程。存储过程可以极大地增强 SQL 的有效性、灵活性和功能性,也能够大大提高 SQL 语句和批处理的性能。许多服务器都提供了存储过程,以便对服务器的数据库对象进行定义和操作,而且实施服务器系统和用户管理。

注释 本章中,使用的示例除特别声明外,都使用的是 Microsoft SQL Server 语法。

若要调用一个服务器存储过程

例如,下面的代码将显示 SQL Server 上名为 sp_who 的存储过程的调用结果。该 SQL Server 使用一个活动的连接与名字为 sqlremote 的数据源相连。

nConnectionHandle = SQLCONNECT('sqlremote')
? SQLEXEC(nConnectionHandle, 'use pubs')
? SQLEXEC(nConnectionHandle, 'sp_who')
BROWSE

有关建立和执行服务器上存储过程的详细信息,请参阅您的服务器文档。

返回多个结果集

如果执行了一个存储过程,该过程包含了本地服务器的语法:即 SELECT 语句,则每个结果集将分别返回到一个独立的 Visual FoxPro 临时表中。使用这些临时表,可以从一个服务器存储过程向 Visual FoxPro 客户机上返回值或者参数。

若要返回多个结果集

例如,下面的代码建立和执行了一个 SQL 服务器存储过程 my_procedure,该过程返回三个 Visual FoxPro 的临时表:sqlresult, sqlresult1sqlresult2

=SQLEXEC(nConnectionHandle,'create procedure my_procedure as ;
      select * from sales; select * from authors; 
      select * from titles')
=SQLEXEC(nConnectionHandle,'execute my_procedure')

服务器如何处理结果集合和错误

由于在建立存储过程时,服务器对每个存储过程进行编译,所以在建立存储过程阶段,可以看到任一服务器语法错误。当执行存储过程时,服务器将依次执行编译过的 SQL 语句(就象 Visual FoxPro 中的程序一样),然后 Visual FoxPro 按照执行的顺序,在存储过程内从每个 SQL 语句中取出每个结果集。

结果集和错误按照接收的顺序返回。当遇到一个错误时,处理过程就会停止。例如,假设服务器正在执行一个包含四条语句的存储过程,当在执行第三条语句时发生了“运行时刻错误”,那么,只能接收前两个结果集,以及处理第三个结果集时的错误。在返回错误信息之后,处理过程中断,不会继续处理第四个结果集。可以使用 AERROR( ) 函数得到最近发生的错误信息。

注释 只有通过 Visual FoxPro SQL pass-through 函数,才能在 Visual FoxPro 中执行服务器存储过程。视图不支持服务器存储过程,因为每个视图在它的 SQL 定义中包含一个显式的 SQL SELECT 语句。

向数据源传递 SQL 语句

可以使用 SQLEXEC( ) 函数将一条 SQL 语句不经任何解释发送到数据源。在最简单的情况下,SQLEXEC( ) 函数第二个参数中包含的所有字符串都不经过任何解释便传递给数据源。这样,就可以执行数据源当地的任何 SQL 语句。

SQLEXEC( ) 函数还可以用来创建参数化查询,或将 SQL 的 ODBC 扩展传递到数据源。

建立参数化查询

如同使用“视图设计器”或以编程方式创建参数化视图一样,也可以创建 SQL pass-through 的参数化查询。

若要用 SQL pass-through 创建一个参数化查询



如果想提示用户输入参数值,可把参数表达式用引号括起来。有关提示输入参数值的详细内容,请参阅第八章“创建视图”

ODBC 数据源不接受下列位置中的参数:

在一个 SELECT 语句的 WHERE 或 HAVING 子句中,ODBC 数据源不接受下列情况的参数:

使用 SQL Server 的输入/输出参数

可以使用输入/输出参数在 Visual FoxPro 和 SQL Server 之间传递参数。只有在使用 SQL pass-through 功能时才可以使用输入/输出参数,在视图中则不能使用它们。

下表提供了一个示例,介绍如何使用输入/输出参数来实现从 Visual FoxPro 向一个 SQL Server 存储过程传递值,并把结果返回到一个 Visual FoxPro 变量中。

在一个 SQL Server 存储过程中使用输入/输出参数

代码 注释
resultCode = SQLExec(connHand,
   "CREATE PROCEDURE sp_test;
      @mult1 int, @mult2 int, @result int;
   OUTPUT AS SELECT
      @result = @mult1 * @mult2")
建立一个名字为 sp_test 的存储过程,该过程将两个变量相乘(mult1mult2),然后将结果保存在变量 result 中。
outParam = 0
建立一个 Visual FoxPro 变量,接收从 SQL Server 向 Visual FoxPro 传递的输出参数值。
resultCode = SQLExec(connHand, ;
"{CALL sp_test (2, 4, ?@outParam)}")
执行该 SQL Server 存储过程,传递参数值 ‘2’ 和 ‘4’,准备在存储过程中进行乘法运算。
? "outParam =", outParam  && the value is 8
显示结果参数的值。

定义参数

输出参数的语法是:

?@parameter_name

在执行输入/输出参数时,需要定义包含在 SQL pass-through 命令中的 Visual FoxPro 变量,才能在 SQL 语句中使用此变量。要想成功地使用输入/输出参数发送和接收信息,必须定义:

转换数据类型

Visual FoxPro 使用下面的规则来转换返回的变量值:

在输入/输出参数中,不能使用备注、通用、图片或者 NULL 数据类型。

如果应用程序使用临时表字段作为参数,那么 Visual FoxPro 会试图将结果转换回原始字段的数据类型。

返回参数值

只有在获取了语句的最后一个结果集之后,输入/输出参数才可用。这意味着,只有在发生下列情况之后,输入/输出值才返回给 Visual FoxPro:

如果 SQLEXEC( ) 语句需要多个结果集,那么只有从数据源中获取最后一个结果集之后,输出参数才能保证有效。

建立与远程数据的外部联接

如果服务器支持外部联接的话,就可以使用服务器本地语法,使用 SQL pass-through 实现和远程数据的外部联接。无论是否找到满足条件的记录行,外部联接都将一个或多个表的信息合并起来。

若要在服务器上实现外部联接



有关外部联接的语法和类型的详细信息,请参阅您的服务器文档。有关建立一个命名联接的信息,请参阅第八章“创建视图”中的“定义联接”部分。

对 SQL 实施 ODBC 扩展

可以使用 SQLEXEC( ) 函数来实现 SQL 的 ODBC 扩展,方法是把 SQL Access Group 的标准语法或扩展的 escape 语法包含到 SQL 语句之中。有关对 SQL 实施 ODBC 扩展的详细内容,请参阅 ODBC 文档中 SQL 语法附录部分。

使用 ODBC Escape 子句建立外部联接

如果服务器支持外部联接,可以使用 ODBC 的 escape 语法,用 SQL pass-through 功能实现和远程数据的外部联接。无论是否找到满足条件的记录行,外部联接都将一个或多个表的信息结合起来。

使用 ODBC escape 子句的外部联接的语法是:

{oj outer-join expression}

下面的示例中,将建立一个 544 号项目的雇员名字和部门的结果集:

SELECT employee.name, dept.deptname;
   FROM {oj employee LEFT OUTER JOIN dept;
            ON employee.deptid = dept.deptid};
   WHERE employee.projid = 544

有关外部联接语法和外部联接类型的详细信息,请参阅您的服务器文档。有关建立一个命名联接的信息,请参阅第八章“创建视图”中的“定义联接”部分。

用 SQL pass-through 管理连接

在创建一个远程视图时,需要选择一个 ODBC 数据源名称或者一个连接名称,作为活动视图与远程服务器之间的数据通道。要用 SQL pass-through 直接访问远程数据,必须拥有活动连接的句柄。句柄实际上是一个指向某一对象的值;在这儿,句柄指向的是一个数据源连接。为了获得一个句柄,可以用 SQLCONNECT( )SQLSTRINGCONNECT( ) 函数来请求一个与数据源的连接。如果连接成功,则应用程序得到连接句柄,在以后的 Visual FoxPro 调用中就可以使用此句柄。

应用程序可以对同一数据源请求多个连接。也可以通过对每一数据源都请求一个连接,同时处理多个 ODBC 数据源。如果想减少使用的连接数目,可以设置远程视图共享相同的连接。使用 SQLDISCONNECT( ) 函数可以切断与数据源的连接。

提示 Visual FoxPro 依赖于对 ODBC 数据源的定义来连接一个数据源,这个定义存储在 Windows ODBC.INI 文件或者 Windows NT 的注册表中。如果更改一个数据源的名称或注册信息,请注意这些更改可能影响到使用该数据源的应用程序与所需远程服务器的连接。

控制环境和连接属性

客户/服务器环境是在每次打开 Visual FoxPro 时建立起来的,此环境的生存期是 Visual FoxPro 的工作期,每次关闭 Visual FoxPro 时,此环境随之消失。客户/服务器环境包括:

可以使用第 0 句柄,也就是“环境”句柄来进行全局属性的设置。要设置属性,可以使用 SQLSETPROP( ) 函数,此函数不但能够控制连接环境的默认属性设置,而且可以控制单个连接的属性。SQLSETPROP( ) 函数设置属性的方法,对于环境连接和单个连接来说都是一致的:

在创建一个新连接时,该连接将继承默认连接的属性值。如果不想使用这些默认值,可以使用 SQLSETPROP( ) 函数来更改。

设置连接属性

可使用 SQLGETPROP( ) 函数以及相应的连接句柄来查看一个连接的当前属性设置。下表列出了可用 SQLGETPROP( ) 函数访问的连接属性。

Visual FoxPro 连接属性

若要 使用此属性 用途
显示用于创建活动连接的信息 ConnectString 注册连接字符串。
DataSource 由 ODBC 定义的数据源名称。
Password 连接密码。
UserID 用户标识符。
在共享连接上工作 ConnectBusy 一个共享连接忙时为“真”(.T.),否则为“假”(.F.)。
控制界面显示 DispLogin 控制何时显示 ODBC 注册对话框。
DispWarnings 控制是否显示非致命错误信息。
控制时间间隔 ConnectTimeout 指定在返回一个连接超时错误之前的等待时间(以秒为单位)。
IdleTimeout 指定空闲超时设定(以秒为单位)。指定活动连接在指定的时间间隔之后变成不活动。
WaitTime 控制以毫秒计的时间量,在经过这段时间之后,Visual FoxPro 检查 SQL 语句是否已执行完毕。
QueryTimeout 控制返回一个一般超时错误之前的等待时间(以秒为单位)。
管理事务处理 Transactions 决定连接如何管理远程表上的事务处理。
控制将结果集合放入到视图临时表中的方式 Asynchronous 指定结果集合是同步返回(默认值)还是异步返回。
BatchMode 指定 SQLEXEC( ) 是一次返回所有结果集(默认值),还是由 SQLMORERESULTS( ) 逐个返回。
PacketSize 指定连接使用的网络包的大小
显示内部 ODBC 句柄 ODBChdbc2 内部 ODBC 连接句柄,可被外部库文件(.fll 文件)用来调用 ODBC API 函数。
ODBChstmt2 内部 ODBC 语句句柄,可被外部库文件(.fll 文件)用来调用 ODBC API 函数。

1.在人工事务处理模式,连接将保持活动状态。

2.如果连接不活动,ODBChdbc 和 ODBChstmt 的值不再有效。 在用户库中不能自由改变这些值。

有关连接属性及其默认设置的详细内容,请参阅 SQLSETPROP( )

控制环境属性设置

用 0 句柄在 Visval FoxPro 环境中设置的值在每一个后续的连接或附件中被作为原型或默认值。

要查看当前环境属性设置

下例将在屏幕上显示当前环境的 WaitTime 属性设置:

? SQLGETPROP(0, "WaitTime")

如果把 DispWarnings 属性设置为“真”(.T.),Visual FoxPro 将从设置时刻开始把所有环境错误显示出来,而且对于以后创建的连接也都设置 DispWarnings 属性为“真”(.T.)。

除了使用句柄 0 设置的值作为原型值用于每个连接以外,还可以为一个单独的连接设置自定义的属性,只要以该连接句柄为参数使用 SQLSETPROP( ) 即可。属性 ConnectTimeout 例外,它在连接时刻便确定了。如果改变 ConnectTimeout 属性设置,新的设置只有重新连接时才能使用。

控制连接和视图对象

通过对连接和视图对象的属性进行设置,以控制连接和视图。那些对数据库、表、表字段、视图定义、视图字段、命名连接、活动连接以及活动的视图临时表进行控制的属性,我们称之为引擎属性。使用如下的 Visual FoxPro 函数,可以显示或者设置引擎属性:

要显示引擎属性,请使用 要设置引擎属性,请使用
CURSORGETPROP( ) CURSORSETPROP( )
DBGETPROP( ) DBSETPROP( )
SQLGETPROP( ) SQLSETPROP( )

要使用什么样的函数,主要依赖于是否想为对象 0(连接 0 和 临时表 0)、数据库中的对象定义(命名连接定义或视图定义)以及活动对象(活动连接或活动的视图临时表)设置属性。下表中,列出了对象以及要为该对象设置属性的函数:

为以下对象设置属性 连接 视图
对象 0 SQLSETPROP( ) CURSORSETPROP( )
数据库中的对象定义 DBSETPROP( ) DBSETPROP( )
活动对象 SQLSETPROP( ) CURSORSETPROP( )

引擎属性

下表中,按照字母的顺序列出了引擎属性,同时注明每个属性所适用的对象。

引擎属性 适用于
Asynchronous 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
Batchmode 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
BatchUpdateCount1 视图定义,请参阅函数 DBSETPROP( )
活动视图临时表,请参阅函数 CURSORSETPROP( )
Buffering 活动视图临时表,请参阅函数 CURSORSETPROP( )
Caption 表和视图定义中的字段,请参阅函数 DBSETPROP( )
Comment 数据库、表、表中字段、视图定义、视图定义中的字段以及连接定义,请参阅函数 DBSETPROP( )
CompareMemo 视图定义,请参阅函数 DBSETPROP( )
活动视图临时表,请参阅函数CURSORSETPROP( )
ConnectBusy 活动连接,请参阅函数 SQLGETPROP( )
ConnectHandle 活动的视图临时表,请参阅函数 CURSORGETPROP( )
ConnectName1 视图定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLGETPROP( )
活动视图临时表,请参阅函数 CURSORGETPROP( )
ConnectString 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLGETPROP( )
ConnectTimeout 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
Database 活动视图临时表,请参阅函数 CURSORGETPROP( )
DataSource 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLGETPROP( )
DataType 在视图定义中的字段,请参阅函数 DBSETPROP( )
DefaultValue 在表和视图定义中的字段,请参阅函数 DBSETPROP( )
DeleteTrigger 表,请参阅函数 DBGETPROP( )
DispLogin 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
DispWarnings 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
FetchAsNeeded 视图定义,请参阅函数DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
FetchMemo1 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
FetchSize1 视图定义,请参阅函数 DBSETPROP( )
活动视图临时表,请参阅函数 CURSORSETPROP( )
IdleTimeout 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
InsertTrigger 表,请参阅函数 DBGETPROP( )
KeyField 在视图定义中的字段,请参阅函数 DBSETPROP( )
KeyFieldList2 活动的视图临时表,请参阅函数 CURSORSETPROP( )
MaxRecords1 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )
ODBCHdbc 活动连接,请参阅函数 SQLGETPROP( )
ODBCHstmt 活动连接,请参阅函数SQLGETPROP( )
Offline 视图定义,请参阅函数DBGETPROP( )
PacketSize 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
ParameterList 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )
Password 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLGETPROP( )
Path 表,请参阅函数 DBGETPROP( )
Prepared 视图定义,请参阅函数 DBSETPROP( )
PrimaryKey 表,请参阅函数 DBGETPROP( )
QueryTimeOut 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
RuleExpression 表、表中字段、视图定义、视图定义中的字段,请参阅函数 DBSETPROP( )
RuleText 表、表中字段、视图定义、视图定义中的字段,请参阅函数 DBSETPROP( )
SendUpdates2 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )
ShareConnection 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
SourceName 活动的视图临时表,请参阅函数 CURSORGETPROP( )
SourceType 视图定义,请参阅函数 DBGETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
SQL 视图定义,请参阅函数 DBGETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
Tables2 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )
Transactions 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
Updatable 视图定义中的字段,请参阅函数 DBSETPROP( )
UpdatableFieldList2 活动的视图临时表,请参阅函数 CURSORSETPROP( )
UpdateName 视图定义中的字段,请参阅函数 DBSETPROP( )
UpdateNameList2 活动视图临时表,请参阅函数 CURSORSETPROP( )
UpdateTrigger 表,请参阅函数 DBGETPROP( )
UpdateType 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )
UseMemoSize1 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORGETPROP( )
UserID 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLGETPROP( )
Version 数据库,请参阅函数 DBGETPROP( )
WaitTime 连接定义,请参阅函数 DBSETPROP( )
活动连接,请参阅函数 SQLSETPROP( )
WhereType 视图定义,请参阅函数 DBSETPROP( )
活动的视图临时表,请参阅函数 CURSORSETPROP( )

1.属性主要用于远程视图;对本地视图设置此属性不起作用。如果想在本地视图中预先设置这个属性,可以在本地视图中设置此属性,升迁后再创建远程视图。

2.为了将更新传送到远程数据源必须设置引擎属性。

对远程数据使用事务处理

可用下列两种方法中的一种,使用事务处理方式来进行远程数据的更新、删除和插入等操作:

所选择的事务处理模式将决定 Visual FoxPro 在本地机器上处理事务的方式。

使用自动事务处理模式

在默认情况下,Visual FoxPro 自动为发送给远程服务器的每一个可事务化的命令包装一个事务处理的外壳。这个默认的自动事务处理只有在 Transactions 属性设置为 1(或 DB_TRANSAUTO)时才产生。

若要使用自动事务处理模式

远程表上的事务处理将自动进行。

注释 Visual FoxPro 的 BEGIN TRANSACTIONEND TRANSACTION 命令只为本地 Visual FoxPro 临时表创建事务处理。它们不能把事务处理扩展到远程服务器上。

人工控制事务处理

如果想人工控制事务处理,可以设置 Transactions 属性为 2 或 DB_TRANSMANUAL。如果采用人工事务处理模式,Visual FoxPro 将在发出第一个可事务化的 SQL 语句时,自动开始一个事务处理,但必须使用 Visual FoxPro 的 SQLCOMMIT( ) 或 SQLROLLBACK( ) 函数来结束这个事务处理。

若要使用人工事务处理模式

通过 SQLCOMMIT( )SQLROLLBACK( ) 函数将进行人工事务处理。

在提交或回滚前一个事务处理之后,Visual FoxPro 在您发出下一个可进行事务处理的 SQL 语句时,自动开始一个新的事务处理。有关事务的详细内容,请参阅第十七章“共享访问程序设计”

嵌套事务处理

Visual FoxPro 支持最多五层的本地数据事务处理嵌套。单层事务处理的支持已内置到 SQL pass-through 中。

如果服务器支持多层事务处理,那么可用 SQL pass-through 来明确地管理事务处理的层数。但是这种明确的事务处理管理方式很复杂,因为很难控制内置事务处理和远程服务器事务处理之间的相互作用。有关明确的事务处理管理的详细内容,请参阅您的 ODBC 文档。

用 SQL pass-through 处理远程数据

用 SQL pass-through 检索一个结果集合之后,可用 Visual FoxPro 函数 CURSORGETPROP( )CURSORSETPROP( ) 来查看和控制结果集合的临时表属性。在对一个活动视图临时表的属性进行设置时,所用的函数与这些函数相同。

注释 临时表不是对象,因而与对象模式无关。但是,可用 CURSORGETPROP( ) 查看它们的属性,用 CURSORSETPROP( ) 设置它们的属性。

设置远程数据的临时表属性

下表列出 Visual FoxPro 临时表的属性,这些属性适用于视图和连接的结果集合,并按任务类型分组。

Visual FoxPro 临时表属性

任务 属性 用途
视图临时表定义 SQL 存放用以生成临时表的 SQL 语句。
控制 Visual FoxPro 和 ODBC 之间的相互作用 ConnectHandle 临时表所使用的远程连接的句柄。
ConnectName 临时表所使用的连接名。
Prepare 指定在执行视图查询之前,是否进行准备。
FetchAsNeeded 在空闲循环期间或者仅在必要时,指定是否自动对行存取。
CompareMemo 无论 UpdateType 属性如何设置,指定在 UPDATE 语句的 WHERE 子句中,是否包含备注和通用字段。
FetchMemo 指定备注和通用字段是随结果集合一起自动获取,还是在备注和通用字段打开时,根据要求来获取。
UseMemoSize 将结果返回到备注字段的列的最小宽度(1 到 255)。
FetchSize 指定每次从远程表中所取得的记录数。
MaxRecords 返回结果集合时获取的最大行数。
更新数据 SendUpdates* 指定对临时表的更新是否发送到临时表所基于的表中。
BatchUpdateCount 指定发送到后台缓冲表的 update 语句数量。
Tables* 以逗号分隔的数据源上的表名列表;用于定义 UpdateNameList 和 UpdatableFieldsList 属性的范围。
KeyFieldList* 以逗号分隔的 Visual FoxPro 字段的列表,字段中包括用于更新的结果集合的主关键字。
UpdateNameList* 以逗号分隔的、与临时表中的 Visual FoxPro 字段相对应的、接收更新的表名及列名。
UpdatableFieldList* 以逗号分隔的、要更新的 Visual FoxPro 字段的列表。
Buffering 指定在临时表上使用的缓冲类型。
UpdateType 指定是使用 UPDATE 命令还是联合 DELETE 和 INSERT 命令进行更新。
WhereType 指定在对表数据进行更新时,应该在 WHERE 子句中包含什么内容。

*必须在更新数据之前设置的属性。

可用这些属性来控制应用程序与远程数据交互作用的方式,比如控制逐步获取时检索的行数、控制对远程数据的缓冲以及对远程数据的更新等。

使用选项对话框中的远程数据选项卡

某些临时表属性的初始值是从环境继承的;其他属性则只在临时表级才可用。一些属性只对特定的临时表可用,这些临时表代表了远程视图和通过 ODBC 或 SQL pass-through 连接的表。

可通过“选项”对话框的“远程数据”选项卡来控制某些临时表和连接的属性设置。显示“远程数据”选项卡时,在对话框中的值代表当前工作期的临时表设置,以及连接的 Visual FoxPro 全局默认设置。在更改了“远程数据”选项卡中的值并且选择“确定”按钮时,新值保存到临时表的当前工作期和连接的全局默认设置中。如果选择“设置为默认值”,这些值写入本地机的可配置系统设置中。下图说明了这些交互作用。

使用“选项”对话框,查看和设定全局设置和工作期设置

用 SQL pass-through 设置属性

在新建一个临时表时,临时表从环境临时表或者当前工作期的 0 号临时表中继承属性设置,比如 UpdateType 和 UseMemoSize。可用 CURSORSETPROP( ) 函数并以 0 做为临时表编号,来更改这些默认属性设置。

用 SQL pass-through 创建一个视图临时表之后,可用 CURSORSETPROP( ) 函数更改活动视图临时表的属性设置。用 CURSORSETPROP( ) 进行的更改是临时的;在关闭视图时,活动视图的临时设置也将消失;在关闭 Visual FoxPro 工作期时,第 0 号临时表的临时设置也随之消失。

连接继承属性的方式与此类似,在数据库中创建并保存一个命名连接时,此连接将默认地继承第 0 号连接的属性。可用 SQLSETPROP( ) 函数改变第 0 号连接的这些默认属性设置。在新建了一个连接并且将其存入数据库以后,可用 DBSETPROP( ) 函数更改连接属性。使用连接时,活动连接将继承存储在数据库中的该连接的属性设置。可用 SQLSETPROP( ) 函数以该活动连接的句柄为参数,更改这些属性。

SQL pass-through 的视图临时表和命名连接都能使用命名的 ODBC 数据源。如果在一个 SQL pass-through 的视图临时表中使用 ODBC 数据源,该连接将从工作期默认值中继承属性。

下图说明了由 SQL pass-through 创建的临时表和连接的属性继承关系。灰线代表属性继承关系;黑线代表 Visual FoxPro 命令。

SQL pass-through (SPT) 创建的连接和临时表的属性继承关系

用 SQL pass-through 更新远程数据

使用 SQL pass-through 函数来更新一个远程服务器上的数据时,通过设置结果集合临时表的属性,不但可以决定是否进行更新,而且可以控制有关更新的具体细节。这样,在请求一个更新时,Visual FoxPro 会在提交更新之前检查这些属性。

若要更新远程数据必须设置五个属性:Tables、KeyFieldList、UpdateNameList、UpdatableFieldList 和 SendUpdates。还可以指定其他属性,比如 Buffering、UpdateType 和 WhereType 以更好地满足应用程序的要求。

若要使活动视图临时表可更新

对活动视图临时表设置的更新属性与 DBSETPROP( ) 设置的更新属性稍有不同。下表列出视图定义和活动临时表分别使用的属性名。

视图和临时表更新属性

用途 视图定义属性1 活动临时表属性2
使远程表可更新。 Tables Tables
指定视图字段的远程名称。 UpdateName(字段级属性) UpdateNameList
指定要做为关键字的视图字段。 KeyField(字段级属性) KeyFieldList
指定可更新的视图字段。 Updatable(字段级属性) UpdatableFieldList
允许更新。 SendUpdates SendUpdates

1 用 DBSETPROP( ) 来设置。
2 用 CURSORSETPROP( ) 来设置。

有关设置更新属性的详细内容,请参阅第八章“创建视图”,或 DBSETPROP( )CURSORSETPROP( )

控制远程更新的时间

通过设置临时表的 Buffering 属性,可以控制如何缓冲对远程数据的更新。在五个可能的缓冲属性设置中,有两个对远程视图有效:

Visual FoxPro 在远程临时表上只支持开放式锁定。

注释 保守式的行缓冲和表缓冲设置(2 和 4)不能应用于远程视图,因为 Visual FoxPro 不能锁定服务器上的数据。而 Buffering 属性设置为 1 也不能应用于远程视图,因为视图经常放在缓存里。

使用开放式行缓冲

默认的 Buffering 设置是 DB_BUFOPTROW,对远程数据进行开放式逐行锁定。例如,如果要逐行提交对 titles 表的更新,比如使用 SKIP 命令时,可把 Buffering 属性设置为 3:

CURSORSETPROP('buffering', 3, 'titles')

当 Buffering 设置成行缓冲时,可用两种方法向远程服务器发送更新:

TABLEUPDATE( ) 函数更新服务器但并不移动记录指针。移动记录指针的命令向远程服务器发送更新,做为指针移开该记录的附带操作。

若用行缓冲并且希望能还原对行的更改,必须用 SQL pass-through 的事务处理函数将这些更改放入一个事务中。

使用开放式表缓冲

若要每次成批提交对一个表的更改,比如用户在一个表单中单击“保存”或“确定”按钮时执行一个批处理操作,这时,必须把 Buffering 属性设置为 5 或 DB_BUFOPTTABLE。必须调用 TABLEUPDATE( ) 函数来向服务器发送更新。

下面的示例在表单的初始化代码中设置 Buffering 属性,然后在进行保存的代码中提交更改。

代码 注释
CURSORSETPROP('buffering', 5, 'sqltitles')
在初始化代码中设置
* 成批更新所做的修改;
* 不管其他人所做的修改
TABLEUPDATE(.T., .T., 'titles')
在进行保存的代码中设置

若要恢复一个表的原始值,并且阻止更新发送给远程服务器,可以调用 TABLEREVERT( )。通过设置临时表的 Buffering 属性并发出 TABLEREVERT( ) 命令,可以控制是恢复单独一行还是所有的行。下面的示例只恢复当前行。可在代码中加入此语句,当用户单击表单中的“取消”按钮时执行此代码:

= TABLEREVERT(.F., 'titles')      && 恢复当前的行

若要恢复所有的行,比如当用户按 ESC 键离开一个表单时,可以使用与此相同的代码。但需要更改 Buffering 属性的设置,同样用 TABLEREVERT( ) 命令,根据整个缓冲表来恢复所有的行:

= TABLEREVERT(.T., 'titles')      && 恢复所有的行

有关缓冲的详细内容,请参阅第十七章“共享访问程序设计”

检测其他用户的更改

在多用户应用程序中,与其他用户的更新冲突由 SQL Update 查询检测,此查询在试图进行一个本地的写操作时,生成这个查询。检测的级别依赖于 CURSORSETPROP( ) 中 WhereType 属性的设置。有关设置 WhereType 属性的详细内容,请参阅第八章“创建视图”

强制更新

可用 TABLEUPDATE( ) 函数控制在发送对表或临时表的更新时,是否要覆盖网络上其他用户对它的更新。若把 TABLEUPDATE( ) 的 Force 参数设置为“真”(.T.),并用 CURSORSETPROP( ) 将 UpdateType 属性设置为默认值 1,那么只要远程表上的记录的关键字段值没有被更改,旧的数据就将被最近发送的新数据所更新。如果远程表的关键字段值已被更改,或者 UpdateType 属性设置为 2,那么 Visual FoxPro 先向远程表发送一条 DELETE 语句,然后再发送一条 INSERT 语句。

更新错误信息答疑

下表列出了特别应用于远程更新的 Visual FoxPro 和 ODBC 错误信息。“操作”栏包含了解除错误所应采取的操作。

错误信息 解释 操作
没有更新指定的表。请使用临时表的 Tables 属性。 临时表的 Tables 属性没有包含远程表名。要能对远程服务器进行更新,最少需要一个表。 使用 Tables 属性为该临时表指定最少一个表。
没有指定更新表 table_name 的关键字的列(有可能是多个列)。请使用临时表的 Key FieldList 属性。 在错误信息中指出的远程表的主关键字没有包括到临时表的 KeyFieldList 属性中,每个更新的表都需要一个主关键字。 用 KeyFieldList 属性指定远程表的主关键字。
column_name 中没有指定合法的更新表。请使用临时表的 UpdateNameList 和 Tables 属性。 column_name 中的 UpdateName 属性包含一个非法的表名。 用 UpdateNameList 属性设置表名,或把表名添加到 Tables 属性设置中,或者两者都做。
临时表的 KeyFieldList 属性没有定义一个唯一的关键字。 多个远程记录具有相同的关键字。 用 KeyFieldList 属性为远程表定义一个唯一的关键字。
来自于 ODBC:ODBC 非法对象。 ODBC 不能找到远程表或者列,因为指定名称的表或列并不存在。Visual FoxPro 字段名由 Visual FoxPro 检查,远程表和列名只由远程服务器检查。 检查对象的名称。

有关错误处理的详细信息,请参阅本章后面的“处理 SQL pass-through 错误”

选择有效的 SQL pass-through 处理方式

Visual FoxPro提供了用 SQL pass-through 来检索和更新远程数据的两种处理方式:同步和异步。使用 SQL pass-through 函数时,可以选择喜欢的方式。对于远程视图,不需要选择方式;Visual FoxPro 对远程视图自动采用逐步获取技术,并且管理这种远程视图的处理方式。

同步方式的优点

默认情况下,以同步方式处理 Visual FoxPro SQL 函数:Visual FoxPro 直到一个函数调用完成时,才把控制权返回给应用程序。与 Visual FoxPro 交互工作时,同步处理方式是很有用。

异步方式的优点

异步处理比同步处理具有更大的灵活性。例如,当应用程序异步处理一个函数时,应用程序可以建立一个进度指示器来显示正在执行的语句的进展情况,显示鼠标指针的运动,创建循环并且设置时钟使得占用时间过长的处理过程自动中断。

异步使用 SQL pass-through

应用程序可为四个用以向数据源发出请求、检索数据的函数申请异步处理方式。它们是:SQLEXEC( )SQLMORERESULTS( )SQLTABLES( )SQLCOLUMNS( )。可以使用 SQLSETPROP( ) 函数设置连接的 Asynchronous 属性,以启用异步处理方式;一旦建立了该连接的异步通信方式,所有这四个函数都将以异步方式进行操作。

若要检查 Asynchronous 属性的设置

若要允许异步处理

在异步方式下,必须重复地调用每个函数,直到返回一个非 0 值(0 表示仍在运行)。如果 SET ESCAPE 设置为“真”(.T.),则在函数运行过程中,可以按 ESC 键取消对函数的处理。

只有在原来就与连接句柄相关的 SQLCANCEL( ) 或者异步函数(SQLEXEC( )SQLMORERESULTS( )SQLTABLES( )SQLCOLUMNS( ))结束处理时,应用程序才能使用该连接句柄。在一个函数结束之前,不能把该函数使用的连接句柄用于其他三个异步函数或者 SQLDISCONNECT( ) 函数。

处理多个结果集合

SQLEXEC( ) 函数发出多个 SQL SELECT 语句,或者执行一个用来发出多个 SELECT 语句的存储过程时,应用程序都会检索多个结果集合。每个 SQL SELECT 语句的结果都返回在一个独立的 Visual FoxPro 临时表中。

第一个临时表的默认名称是 SQLRESULT,在该默认名的基础上加上数字就得到后续的临时表的名称。例如,由 SQLEXEC( ) 语句返回的三个结果集合的临时表默认名是:Sqlresult、Sqlresult1 和 Sqlresult2。

在批处理方式下,如果一个函数返回多个结果集合,在 Visual FoxPro 中各个临时表名都具有唯一的后缀,并且能达到 255 个字符。例如,下例把 BatchMode 属性设置为批处理方式,然后发出一个 SQLEXEC( ) 语句,其中包含有四个 SQL SELECT 语句,得到四个结果集合。

? SQLSETPROP(nConnectionHandle,'BatchMode', .T.) 
? SQLEXEC(nConnectionHandle,'select * from authors ; 
                     select * from titles ; 
                     select * from roysched ; 
                     select * from titleauthor','ITEM')

当上述函数处理完成以后,Visual FoxPro 以临时表 Item、Item1、Item2 和 Item3 的形式返回四个结果集合。

可以用 SQLEXEC( )SQLMORERESULTS( ) 函数的 cCursorname 参数来更改这个默认名。如果指定的结果集合名已被使用,则新的结果集合将覆盖原来的临时表。

在检索多个结果集合时,应用程序可在同步处理或异步处理、批处理或非批处理方式之间做出选择。

使用批处理方式

SQLSETPROP( ) 函数设置的 BatchMode 属性可以控制 SQLEXEC( ) 返回多个结果集合的方式。此属性的默认值为 1,即批处理方式。批处理方式意味着 Visual FoxPro 的 SQLEXEC( ) 调用只在检索完了所有的单个结果集合后,才返回结果。

使用非批处理方式

如果用 SQLSETPROP( ) 函数把 BatchMode 属性设置为 0,即非批处理方式,那么每个结果集合将单独地返回。第一个结果集合由 SQLEXEC( ) 函数调用返回。其他结果集合必须由应用程序重复调用 SQLMORERESULTS( ) 函数得到。若函数返回值为 2,则表明已没有其他结果。

在非批处理方式中,临时表名可在每一个后继的 SQLMORERESULTS( ) 调用中更改;因此,如果上例中第一个临时表为 Item,并且第二个 SQLMORERESULTS( ) 调用把 cCursorName 参数更改为 Otheritem,那么结果临时表名就为 Item、Item1、Otheritem 和 Otheritem1。

下面一节将详细说明批处理与非批处理、同步与异步之间的区别。下图显示了四种可能的处理组合,其中数字 0、1、2 分别表示调用每个函数时的返回值。

Visual FoxPro 同步和异步处理方式

每种处理方式将在下面给出说明,在后面的说明中,A、B、C、D 分别代表上图中不同的处理情况。每种情况都假定一条语句返回三个结果集合,在图中用三个水平带区代表。

使用同步处理

在同步方式下,函数在执行完毕以后,才将控制权返回给应用程序。

A:同步批处理方式

在以批处理方式同步执行一条 SQL pass-through 语句时,直到所有结果集合都检索完毕以后,才返回控制权。在最初的函数中,用 cCursorname 参数指定第一个临时表的名称。如果指定的临时表已经存在,结果集合会覆盖原来的临时表。在用同步批处理方式请求多个结果集合时,Visual FoxPro 通过在第一个临时表名的基础上加数字来创建其他的临时表名。

B:同步非批处理方式

在以非批处理方式同步执行一条 SQL pass-through 语句时,第一条语句检索第一个结果集合,并且返回 1。然后,必须重复地调用 SQLMORERESULTS( ) 函数得到其他结果集合,并且可以指定一个新的临时表名。如果不为临时表指定一个新名称,那么会以原来的名称为基础并分别加上数字来创建多个结果集合的多个名称。当 SQLMORERESULTS( ) 返回值为 2 时,说明已没有其他结果。

使用异步处理

在异步方式下,应用程序必须连续地调用同一个 SQL pass-through 函数,直到它返回一个非 0 值(0 表示仍在执行)。默认的结果集合名 Sqlresult,可以在第一次调用函数时通过 cCursorname 参数明确地更改。如果指定的结果集合名已被使用,那么新的结果集合会覆盖原来的临时表中的信息。

C:异步批处理方式

以批处理方式异步执行时,在所有结果集合都返回给指定的临时表之前,对原函数的每一次重复调用都将返回 0(表示仍在执行)。在所有的结果都检索完毕之后,所得到的返回值可能是临时表的编号,也可能是一个负值:表示出错。

D:异步非批处理方式

以非批处理方式异步执行时,SQLEXEC( ) 每完成一个结果集合的检索,就返回 1。应用程序必须重复调用 SQLMORERESULTS( ) 函数,直到返回值为 2,表明已经没有其他结果。

提示 远程结果集合必须经历两个步骤完成检索:首先,在服务器上得到结果集合。然后,结果集合放在一个本地 Visual FoxPro 临时表中。在异步方式下,可调用 USED( ) 函数来查看 Visual FoxPro 是否已开始获取所请求的临时表。

控制数据类型的转换

在远程服务器和 Visual FoxPro 之间转移数据时,多少会遇到服务器上的数据类型与 Visual FoxPro 中的数据类型有差别的情况,远程数据源和 Visual FoxPro 的数据类型完全一一对应的情况是极少的。为了处理这些差别,Visual FoxPro 借助 ODBC 数据类型将远程数据类型映射为本地 Visual FoxPro 数据类型。通过掌握如何在 ODBC 和 Visual FoxPro 之间映射数据类型,可以对 Visual FoxPro 应用程序如何处理服务器上的远程数据做到心中有数。

如果需要,还可以调整在服务器上或者应用程序中使用的数据类型。可以通过为远程数据集合创建一个视图,然后在数据库中设置 DataType 视图字段属性来忽略默认的 Visual FoxPro 字段数据类型。DataType 属性是一个字符属性,指出一个远程视图中每个字段所需的数据类型。有关 DataType 属性的详细内容,请参阅 DBSETPROP( )

下载和上载远程视图数据

从一个远程 ODBC 数据源检索数据时,Visual FoxPro 把每个 ODBC 字段的数据类型转换成结果集合临时表中等价的 Visual FoxPro 数据类型。下表列出 ODBC 数据源上提供的数据类型,以及对应的 Visual FoxPro 的数据类型。

远程字段的 ODBC 数据类型 Visual FoxPro 临时表中字段数据类型
SQL_CHAR
SQL_VARCHAR
SQL_LONGVARCHAR
字符型或备注型1
SQL_BINARY
SQL_VARBINARY
SQL_LONGVARBINARY
备注型
SQL_DECIMAL
SQL_NUMERIC
数值型或货币型2
SQL_BIT 逻辑型
SQL_TINYINT
SQL_SMALLINT
SQL_INTEGER
整型
SQL_BIGINT 字符型
SQL_REAL
SQL_FLOAT
SQL_DOUBLE
双精度型;小数位数由 Visual FoxPro 中 SET DECIMAL 的值决定。
SQL_DATE 日期型
SQL_TIME 日期时间型3
SQL_TIMESTAMP 日期时间型4

1 如果 ODBC 字段宽度小于临时表属性 UseMemoSize 的值,在 Visual FoxPro 临时表中它将变成一个字符型字段;否则,它成为一个备注型字段。
2 如果服务器字段为 money 数据类型,则在 Visual FoxPro 中它变成货币数据类型。
3 日期默认为1/1/1900。
4 如果 SQL_TIMESTAMP 字段的值包含秒的小数部分,则在转换为 Visual FoxPro 的日期时间型数据时,该小数被截断。

注释 在 ODBC 数据源字段中的 null 值在将变成 Visual FoxPro 临时表中的 null 值,应用程序检索远程数据时将忽略 Visual FoxPro 中的 SET NULL 设置。

把 Visual FoxPro 参数转换为远程视图数据类型

如果存于临时表中的 Visual FoxPro 数据来源于远程数据,当这些数据发送给远程服务器时,会转换成它们原来的 ODBC 类型。如果通过 SQL pass-through 把来源于 Visual FoxPro 的数据发送给远程服务器,将进行下面的转换。

Visual FoxPro 数据类型 ODBC 数据类型
字符型 SQL_CHAR 或 SQL_LONGVARCHAR1
货币型 SQL_DECIMAL
日期型 SQL_DATE 或
SQL_TIMESTAMP2
日期时间型 SQL_TIMESTAMP
双精度型 SQL_DOUBLE
整型 SQL_INTEGER
通用型 SQL_LONGVARBINARY
逻辑型 SQL_BIT
备注型 SQL_LONGVARCHAR
数值型 SQL_DOUBLE

1 如果映射为一个参数的 Visual FoxPro 内存变量创建了一个宽度小于 255 的表达式,那么在 ODBC 数据源中它成为 SQL_CHAR 类型;否则,成为 SQL_LONGVARCHAR 类型。
2 对于除 SQL Server 以外的所有其他 ODBC 数据源,Visual FoxPro 日期型数据都被转换为 SQL_DATE 类型,对于 SQL Server,它被转换为 SQL_TIMESTAMP 类型。

把 Visual FoxPro 参数映射为远程数据类型

可把一个 Visual FoxPro 参数值映射为一个特定的远程数据类型,方法是对该参数设置格式,使其成为一个字符表达式,该字符表达式符合对应的远程数据类型的语法要求。例如,如果服务器提供日期时间型数据类型,您可以以该服务器所支持的日期时间型格式为您的 Visual FoxPro 参数创建一个字符表达式,在服务器接收到该参数值的时候,它会尝试把这个经过设置格式的数据映射为日期时间型数据。

注释 在发送一个参数给远程服务器时,必须确保 WHERE 子句中的数据类型与参数表达式中所使用的数据类型相匹配。

处理 SQL pass-through 错误

如果 SQL pass-through 函数返回错误,Visual FoxPro 将把错误信息存储在一个数组中。AERROR( ) 函数能够提供从各个级别组件中检测到的错误信息:Visual FoxPro、ODBC 数据源或者远程服务器。通过检查 AERROR( ) 的返回值,您可以确定所发生的服务器错误以及错误信息的文本。

重要内容 要获得错误信息,必须在发生错误后立即调用 AERROR( )。若在调用 AERROR( ) 之前又发生其他错误,那么前一个错误信息便会丢失。