oracle学习笔记

  数据库知识一直以来是我从来没有好好的研究过的东西, 然而事实上它却是应用的最普遍的知识. 一个做了五年的程序员竟然对数据库知识几乎一无所知, 真的是不太应该. 以前对于数据库的知识始终有一些误解, 认为数据库是非常困难的,尤其是oracle. 其实这都是错觉, 经过了一天的学习, 查资料发现,其实对于一个程序员来说,oracle 并没有想像中那么可怕.

 首先对使用oracle的人进行分类, 一类是DBA, 这些人需要彻底精通oracle的方方面面. 另一类是数据库程序员, 这些人所需要掌握的就少得多了, 因为他们的职责不是管理数据库, 而是操作数据库. 具体的职责是, 使用某些工具,比如vc,连接到数据库上, 用SQL语句来操作数据库. 或者再高一些的话, 使用PL/SQL语言来编写存储过程, 以供vc调用. 对于一些小型的数据库项目,也许需要你自己来设计数据库的结构,包括设计多少个表,每个表的结构是什么样的等等.我属于第二类人, 所以对我来说, 主要任务是: 会设计简单的数据库表,掌握SQL,PL/SQL.再会些管理方面的简单知识就好了,比如说创建个用户了,更改下密码了.到达这种程度最多也就是一个月的时间就足够了.

  数据库, 它的最基本的功能就是存储数据, 主要方式是表的方式. 数据存储起来了以后,还要提供途径供人操作,比如查询,修改等等. 你可以直接在数据库中查看,编辑,但是那样非常麻烦,不方便. 所以后来开发出了SQL, 我们调用这些语句就可以实现对应的功能. 在oracle中, 我们可以使用oracle自带的工具sql*plus, 它可以用来执行SQL语句.

  sql*plus功能: 执行命令,比如show user, exit等. 执行sql语句. 编译存储过程, 执行存储过程.

接下来的任务:

 1 学习设计小型数据库(使用c++ builder 数据库开发经典案例解析)

 2 复习SQL.(使用数据库系统原理教程)

3 学习pl/sql(使用OReilly.Oracle.PL.SQL.Programming.4th.Edition.Aug.2005)

4 学习日常管理(练习sql*plus)

5 学习vc操作数据库的方法(inside vc++)

 

使用SQL的三种方式:

1 是自主式. 比如在SQL*PLUS中直接使用SQL语句来执行相应的操作.

2 是嵌入式. 比如在c语言中嵌入SQL语句. 在所有的SQL语句前要加关键词exec SQL

3 利用应用程序编程接口.比如odbc.

 

关于嵌入式的用法:

嵌入式SQL编程[搜集]
 
来源: ChinaUnix博客  日期: 2006.05.06 11:50 (共有0条评论) 我要评论
 

转自
http://www.ianywhere.com
简介
[嵌入式 SQL] 是用于 C 和 C++ 编程语言的数据库编程接口。它由混杂在(嵌入于) C 或 C++ 源代码中的 SQL 语句组成。这些 SQL 语句先由 SQL 预处理器转换为 C 或 C++ 源代码,然后您再进行编译。
在运行时,嵌入式 SQL 应用程序使用 Adaptive Server Anywhere 接口库数据库服务器进行通信。在大多数平台上,接口库是一个动态链接库 (DLL) 或共享库。


  • 在 Windows 操作系统上,接口库是 dblib9.dll

  • 在 UNIX 操作系统上,接口库会是 libdblib9.solibdblib9.sllibdblib9.a(视操作系统而定)。

Adaptive Server Anywhere 提供了两种嵌入式 SQL。静态嵌入式 SQL 使用起来比较简单,但它不如动态嵌入式 SQL 灵活。在本章中将对这两种嵌入式 SQL 进行讨论。
开发过程概述


在对程序成功地进行预处理和编译后,就可以将它与 Adaptive Server Anywhere 接口库的导入库链接在一起,以形成可执行文件。在运行数据库时,这个可执行文件使用 Adaptive Server Anywhere DLL 与数据库交互作用。在对程序进行预处理时,不必运行数据库。
对于 Windows,Watcom C/C++、Microsoft Visual C++ 和 Borland C++ 各自有单独的导入库。
使用导入库是开发调用 DLL 中函数的应用程序的标准方法。Adaptive Server Anywhere 还提供了另外一种方法来避免使用导入库(建议使用此方法)。有关详细信息,请参见
动态装载接口库

运行 SQL 预处理器
SQL 预处理器是一个名为 sqlpp.exe 的可执行文件。
命令行
SQLPP 命令行如下:
sqlpp [ options ] sql-filename [output-filename]
在运行 C 或 C++ 编译器之前,SQL 预处理器处理含有嵌入式 SQL 的 C 程序。预处理器将 SQL 语句转换为 C/C++ 语言源代码,并置于输出文件中。含有嵌入式 SQL 的源程序的扩展名通常为 .sqc。缺省的输出文件名是 sql-filename,其扩展名为 .c。如果 sql-filename 已经具有 .c 扩展名,则缺省情况下输出文件扩展名为 .cc
有关命令行选项的完整列表,请参见
SQL 预处理器

支持的编译器
C 语言 SQL 预处理器已经可以与下列编译器联合使用:
操作系统
编译器
版本
Windows
Watcom C/C++
9.5 及更高版本
Windows
Microsoft Visual C/C++
1.0 及更高版本
Windows
Borland C++
4.5
Windows CE
Microsoft Visual C/C++
5.0
UNIX
GNU 编译器或本地编译器
NetWare
Watcom C/C++
10.6, 11
有关构建 NetWare NLM 的说明,请参见
构建 NetWare 可装载模块

嵌入式 SQL 头文件
所有头文件都安装在您的 SQL Anywhere 安装目录的 h 子目录中。
文件名
说明
sqlca.h
包括在所有嵌入式 SQL 程序中的主头文件。此文件包括 [SQL 通信区域](SQLCA) 的结构定义和所有嵌入式 SQL 数据库接口函数的原型。
sqlda.h
包括在使用动态 SQL 的嵌入式 SQL 程序中的 [SQL 描述符区域] 结构定义。
sqldef.h
嵌入式 SQL 接口数据类型的定义。此文件还包含从 C 程序启动数据库服务器所需的结构定义和返回代码。
sqlerr.h
在 SQLCA 的 sqlcode 字段中返回的错误代码的定义。
sqlstate.h
在 SQLCA 的 sqlstate 字段中返回的 ANSI/ISO SQL 标准错误状态的定义。
pshpk1.h、pshpk2.h
这些头文件可确保正确地处理结构压缩。它支持 Watcom C/C++、Microsoft Visual C++、IBM Visual Age 和 Borland C/C++ 编译器。
导入库
所有导入库都安装在 SQL Anywhere 安装目录的操作系统子目录下的 lib 子目录中。例如,Windows 导入库存储在 win32/lib 子目录中。
操作系统
编译器
导入库
Windows
Watcom C/C++
dblibtw.lib
Windows
Microsoft Visual C++
dblibtm.lib
Windows CE
Microsoft Visual C++
dblib9.lib
NetWare
Watcom C/C++
dblib9.lib
Solaris(非线程应用程序)
所有编译器
libdblib9.so、libdbtasks9.so
Solaris(线程应用程序)
所有编译器
libdblib9_r.so、libdbtasks9_r.so
libdbtasks9 库由 libdblib9 库调用。有些编译器会自动定位 libdbtasks9,而对于其它编译器,则需要您显式指定它。
简单示例
下面是一个非常简单的嵌入式 SQL 程序示例。
#include
EXEC SQL INCLUDE SQLCA;
main()
{
   db_init( &sqlca );
   EXEC SQL WHENEVER SQLERROR GOTO error;
   EXEC SQL CONNECT "DBA" IDENTIFIED BY "SQL";
   EXEC SQL UPDATE employee
      SET emp_lname =    'Plankton'
      WHERE emp_id = 195;
   EXEC SQL COMMIT WORK;
   EXEC SQL DISCONNECT;
   db_fini( &sqlca );
   return( 0 );
      error:
   printf( "update unsuccessful -- sqlcode = %ld/n",
      sqlca.sqlcode );
   db_fini( &sqlca );
   return( -1 );
}
此示例连接到数据库,更新 195 号雇员的姓氏,提交更改,然后退出。实际上 SQL 和 C 代码之间没有交互作用。在本示例中 C 代码仅用于控制流。WHENEVER 语句用于错误检查。错误处理(此示例中的 GOTO)会在任何引起错误的 SQL 语句之后执行。
有关读取数据的说明,请参见
读取数据

嵌入式 SQL 程序的结构
SQL 语句置于(嵌入)常规 C 或 C++ 代码内。所有嵌入式 SQL 语句都以 EXEC SQL 开头,并以分号 (;) 结尾。在嵌入式 SQL 语句的中间允许使用常规 C 语言注释。
使用嵌入式 SQL 的每个 C 程序都必须在源文件中任何其它嵌入式 SQL 语句之前包含以下语句。
EXEC SQL INCLUDE SQLCA;
由 C 程序执行的第一个嵌入式 SQL 语句必须是 CONNECT 语句。CONNECT 语句用于建立与数据库服务器的连接,以及指定连接期间用于授权执行的所有语句的用户 ID。
CONNECT 语句必须是执行的第一个嵌入式 SQL 语句。有些嵌入式 SQL 命令不生成任何 C 代码,或者不会涉及与数据库通信。因此,允许在 CONNECT 语句之前使用这些命令。最主要的是 INCLUDE 语句和指定错误处理方法的 WHENEVER 语句。
动态装载接口库
开发使用 DLL 中的函数的应用程序的通常做法是,把应用程序链接到包含所需函数定义的导入库
本节介绍了在开发 Adaptive Server Anywhere 应用程序时不使用导入库的方法。使用安装目录的 src 子目录中的 esqldll.c 模块,可以动态装载 Adaptive Server Anywhere 接口库,而不必针对导入库进行链接。建议使用 esqldll.c,因为它更易于使用而且其定位接口 DLL 的能力更强。
动态装载接口 DLL:

  • 您的程序必须调用 db_init_dll 才能装载 DLL,而且必须调用 db_fini_dll 才能释放 DLL。必须在调用数据库接口中的所有函数之前调用 db_init_dll,而且在调用 db_fini_dll 之后不能调用接口中的任何函数。
    您还必须调用 db_init db_fini 库函数。

  • 您必须在嵌入式 SQL 程序中的 EXEC SQL INCLUDE SQLCA 语句或 #include  行之前 #include esqldll.h 头文件。

  • 必须定义一个 SQL OS 宏。esqdll.c 包括的头文件 sqlca.h 会尝试确定适当的宏并定义它。但是,平台和编译器的某些组合可能导致此操作失败。在这种情况下,您必须将 #define 添加到此文件的顶部,或者使用编译器选项进行定义。

    平台
    _SQL_OS_WINNT
    所有 Windows 操作系统
    _SQL_OS_UNIX
    UNIX
    _SQL_OS_NETWARE
    NetWare

  • 编译 esqldll.c

  • 将对象模块 esqldll.obj 与您的嵌入式 SQL 应用程序对象链接在一起,而不是针对导入库进行链接。
    示例
    您可以在 SQL Anywhere 目录的 Samples/ASA/ESQLDynamicLoad 子目录中找到一个示例程序,该程序说明如何动态装载接口库。源代码位于 Samples/ASA/ESQLDynamicLoad/sample.sqc 中。
    构建 NetWare 可装载模块
    您必须使用 Watcom C/C++ 编译器 10.6 版或 11.0 版将嵌入式 SQL 程序编译为 NetWare 可装载模块(NLM)。
    创建嵌入式 SQL NLM:

  • 在 Windows 上,使用以下命令对嵌入式 SQL 文件进行预处理:
    sqlpp -o NETWARE srcfile.sqc
    此指令可创建扩展名为 .c 的文件。

  • 使用 Watcom 编译器(10.6 版或 11.0 版)以及 /bt=netware 选项编译 file.c

  • 使用 Watcom 链接器(使用以下选项)链接生成的目标文件:
    FORMAT NOVELL
    MODULE dblib9
    OPTION CASEEXACT
    IMPORT @dblib9.imp
    LIBRARY dblib9.lib
    文件 dblib9.impdblib9.lib 随 Adaptive Server Anywhere 一起提供,它们位于 nlm/lib 目录中。IMPORT 和 LIBRARY 行可能需要完整路径。
    示例嵌入式 SQL 程序
    示例嵌入式 SQL 程序随 Adaptive Server Anywhere 的安装提供,它们位于您的 SQL Anywhere 目录的 Samples/ASA/C 子目录中。


    • 静态游标嵌入式 SQL 示例 Samples/ASA/C/cur.sqc 演示如何使用静态 SQL 语句。

    • 动态游标嵌入式 SQL 示例 Samples/ASA/C/dcur.sqc 演示如何使用动态 SQL 语句。

    为了减少由示例程序的重复代码量,已经将主线和数据打印函数置于单独的文件中。对于字符模式系统,该文件是 mainch.c;对于窗口环境,则是 mainwin.c
    每个示例程序都提供了以下三个从主线调用的例程。


    • WSQLEX_Init    连接到数据库并打开游标。

    • WSQLEX_Process_Command    处理来自用户的命令,根据需要操纵游标。

    • WSQLEX_Finish    关闭游标并断开与数据库的连接。

    主线的功能是:

  • 调用 WSQLEX_Init 例程

  • 执行循环,从用户获取命令并调用 WSQL_Process_Command,直到用户退出

  • 调用 WSQLEX_Finish 例程
    连接到数据库是使用提供适当用户 ID 和口令的嵌入式 SQL CONNECT 命令完成的。
    除了这些示例之外,您还可以找到作为 SQL Anywhere Studio 的一部分、演示可用于特定平台的功能的其它程序和源文件。
    构建示例程序
    用于构建示例程序的文件随示例代码提供。


    • 对于由 Windows 操作系统承载的 Windows 和 NetWare 操作系统,使用 makeall.bat 编译示例程序。

    • 对于 UNIX,使用外壳程序脚本 makeall

    • 对于 Windows CE,使用用于 Microsoft Visual C++ 的 dcur.dsp 项目文件。

    命令格式如下:
    makeall {Example} {Platform} {Compiler}
    第一个参数是您要编译的示例程序的名称。它是以下各项之一:


    • CUR    静态游标示例

    • DCUR    动态游标示例

    • ODBC    ODBC 示例

    第二个参数是目标平台。它是以下各项之一:


    • WINNT    为 Windows 编译。

    • NETWARE    为 NetWare NLM 编译

    第三个参数是用于编译程序的编译器。编译器可以是以下各项之一:


    • WC    使用 Watcom C/C++

    • MC    使用 Microsoft C

    • BC    使用 Borland C

    运行示例程序
    可执行文件以及源代码位于 Samples/ASA/C 目录中。
    运行静态游标示例程序:

  • 启动该程序:


    • 启动 Adaptive Server Anywhere 个人服务器示例数据库。

    • 运行文件 Samples/ASA/C/curwnt.exe

  • 按照屏幕上的说明进行操作。
    各种不同的命令可操纵数据库游标并在屏幕上显示查询结果。键入您希望执行的命令的字母。某些系统可能要求您在键入字母之后按 Enter 键。
    运行动态游标示例程序:

  • 启动该程序:


    • 运行文件 Samples/ASA/C/dcurwnt.exe

  • 连接到数据库:


    • 每个示例程序都提供一个控制台类型的用户界面并提示您输入命令。输入以下连接字符串以连接到示例数据库:
      DSN=ASA 9.0 Sample

  • 选择表:


    • 每个示例程序都提示您选择一个表。选择示例数据库中的一个表。例如,可以输入 CustomerEmployee

  • 按照屏幕上的说明进行操作。
    各种不同的命令可操纵数据库游标并在屏幕上显示查询结果。键入您希望执行的命令的字母。某些系统可能要求您在键入字母之后按 Enter 键。
    Windows 示例
    示例程序的 Windows 版是真正的 Windows 程序。但是,为了使用户界面代码相对简单,已经进行了一些简化。特别是,这些应用程序除了重新打印提示之外,不会针对 WM_PAINT 消息重绘其 Windows。
    静态游标示例
    本示例演示如何使用游标。此处使用的特定游标从示例数据库中的 employee 表检索特定信息。游标是静态声明的,也就是说,检索信息的实际 SQL 语句会被 [硬编码] 到源程序中。这是了解游标工作方式的一个良好起点。下一个示例(
    动态游标示例
    )采用第一个示例并将其转换为使用动态 SQL 语句。
    有关可以在何处找到源代码以及如何构建此示例程序的信息,请参见
    示例嵌入式 SQL 程序

    open_cursor 例程声明特定 SQL 命令的游标并打开此游标。
    显示信息页是由 print 例程完成的。它会循环 pagesize 次,从游标中读取一行并将它显示输出。注意,fetch 例程检查警告条件(如 [未找到行])并显示这些条件出现时的相应消息。另外,此程序会将游标重新定位到出现在当前数据页顶部的行之前的行。
    movetopbottom 例程使用适当形式的 FETCH 语句来定位游标。注意,此形式的 FETCH 语句实际上不获取数据,它只定位游标。另外,move 作为一个通用的相对定位例程,被设计成按照参数的符号上下移动游标。
    在用户退出时,会关闭游标,而且还会释放数据库连接。游标由 ROLLBACK WORK 语句关闭,而连接由 DISCONNECT 释放。
    动态游标示例
    本示例演示如何使用动态 SQL SELECT 语句的游标。它与静态游标示例稍有不同。请先查看
    静态游标示例
    (如果您尚未查看),然后再查看本示例,这样会比较有帮助。
    有关可以在何处找到源代码以及如何构建此示例程序的信息,请参见
    示例嵌入式 SQL 程序

    dcur 程序允许用户选择要使用 n 命令查看的表。然后,该程序会根据屏幕大小尽可能多地显示表中的信息。
    在运行此程序时,它会提示输入以下形式的连接字符串:
    uid=DBA;pwd=SQL;dbf=c:/asa/asademo.db
    含有嵌入式 SQL 的 C 程序位于您的 SQL Anywhere 目录的 Samples/ASA/C 子目录中。除了 connectopen_cursorprint 函数之外,此程序看起来很像静态游标示例。
    connect 函数使用嵌入式 SQL 接口函数 db_string_connect 连接到数据库。此函数还提供额外功能,可支持用于连接数据库的连接字符串。
    open_cursor 例程首先构建 SELECT 语句
    SELECT * FROM tablename
    其中 tablename 是传递给该例程的参数。然后,它使用此字符串准备动态 SQL 语句。
    嵌入式 SQL DESCRIBE 命令用于在 SQLDA 结构中填充 SELECT 语句的结果。
    SQLDA 的大小 最初推测的是 SQLDA 的大小 (3)。如果此值不够大,则会使用数据库服务器返回的选择列表的实际大小来分配一个大小正确的 SQLDA。
    然后,用缓冲区填充 SQLDA 结构以存放代表查询结果的字符串。fill_s_sqlda 例程将 SQLDA 中的所有数据类型转换为 DT_STRING 并分配适当大小的缓冲区。
    然后,为此语句声明并打开游标。用于移动和关闭游标的其余例程保持不变。
    fetch 例程稍有不同:它将结果放在 SQLDA 结构中,而不是放在一组主机变量中。print 例程有很大改动,可按屏幕宽度显示来自 SQLDA 结构的结果。print 例程还使用 SQLDA 的名称字段来显示每列的标题。
    服务示例
    如果要为支持服务的 Windows 版本编译示例程序 cur.sqc dcur.sqc,这两个程序也可以作为服务运行。
    包含 Windows 服务的示例代码的两个文件是源文件 ntsvc.c 和头文件 ntsvc.h。该代码允许链接的可执行文件作为常规可执行文件或者作为 Windows 服务运行。
    将所编译示例之一作为 Windows 服务运行:

  • 启动 Sybase Central。

  • 在左窗格中,选择 [Adaptive Server Anywhere 9]。

  • 在右窗格中,选择 [服务] 选项卡。

  • 从 [文件] 菜单中,选择 [新建]  >  [服务]。
    即会出现 [创建服务] 向导。

  • 在第一页上,输入服务的名称。

  • 在第二页上,选择 [示例] 程序。

  • 在第三页上,从您的 SQL Anywhere 目录的 Samples/ASA/C 子目录,浏览到示例程序(curwnt.exedcurwnt.exe)。

  • 完成向导以安装该服务。

  • 在主窗口中单击 [启动] 以启动服务。
    在作为服务运行时,如有可能程序会显示普通用户界面。这些程序还会将输出写入 [应用程序事件日志]。如果无法启动用户界面,则程序会将一页数据打印到 [应用程序事件日志],然后停止。
    已经使用 Watcom C/C++ 10.5 编译器和 Microsoft Visual C++ 编译器对这些示例进行了测试。
    嵌入式 SQL 数据类型
    要在程序和数据库服务器间传送信息,每个数据都必须有一个数据类型。嵌入式 SQL 数据类型常量以 DT_ 为前缀,并且可以在 sqldef.h 头文件中找到。您可以创建任何一种受支持类型的主机变量。您还可以在 SQLDA 结构中使用这些类型向数据库中传入和从中传出数据。
    您可以使用在 sqlca.h 中列出的 DECL_ 宏定义这些数据类型的变量。例如,使用 DECL_BIGINT 可声明保存有 BIGINT 值的变量。
    以下数据类型受嵌入式 SQL 编程接口的支持:


    • DT_BIT    8 位有符号的整数。

    • DT_SMALLINT    16 位有符号整数。

    • DT_UNSSMALLINT    16 位无符号的整数。

    • DT_TINYINT    8 位有符号的整数。

    • DT_BIGINT    64 位有符号的整数。

    • DT_INT    32 位有符号整数。

    • DT_UNSINT    16 位无符号的整数。

    • DT_FLOAT    4 字节浮点数。

    • DT_DOUBLE    8 字节浮点数。

    • DT_DECIMAL    压缩十进制数。typedef struct DECIMAL {
        char array[1];
      } DECIMAL;

    • DT_STRING    以空值终止的字符串。如果数据库是使用填补空白的字符串进行的初始化,则该字符串是填补空白的。

    • DT_DATE    以空值终止的字符串,是一个有效日期。

    • DT_TIME    以空值终止的字符串,是一个有效时间。

    • DT_TIMESTAMP    以空值终止的字符串,是一个有效时间戳。

    • DT_FIXCHAR    填补空白的定长字符串。

    • DT_VARCHAR    具有双字节长度字段的变长字符串。在为数据库服务器提供信息时,您必须设置长度字段。从数据库服务器读取信息时,服务器设置长度字段(不填补空白)。typedef struct VARCHAR {
         unsigned short int len;
         char array[1];
      } VARCHAR;

    • DT_LONGVARCHAR    长的可变长度字符数据。该宏定义一个如下结构:#define DECL_LONGVARCHAR( size )         /
        struct { a_sql_uint32    array_len;    /
                 a_sql_uint32    stored_len;   /
                 a_sql_uint32    untrunc_len;  /
                 char            array[size+1];/
               }
      DECL_LONGVARCHAR 结构可用于表示大于 32K 的数据。对于较大的数据,可以一次全部读取,也可以使用 GET DATA 语句逐段读取。对于较大的数据,可以一次就全部提供给服务器,也可以通过使用 SET 语句附加到数据库变量中来逐段提供。该数据不是以空值终止的。
      有关详细信息,请参见
      发送和检索 Long 型值

    • DT_BINARY    具有双字节长度字段的变长二进制数据。在为数据库服务器提供信息时,您必须设置长度字段。在从数据库服务器读取信息时,服务器设置长度字段。typedef struct BINARY {
        unsigned short int len;
        char array[1];
      } BINARY;

    • DT_LONGBINARY    长二进制数据。该宏定义一个如下结构:#define DECL_LONGBINARY( size )          /
        struct { a_sql_uint32    array_len;    /
                 a_sql_uint32    stored_len;   /
                 a_sql_uint32    untrunc_len;  /
                 char            array[size];  /
               }
      DECL_LONGBINARY 结构可用于大于 32K 的数据。对于较大的数据,可以一次全部读取,也可以使用 GET DATA 语句逐段读取。对于较大的数据,可以一次就全部提供给服务器,也可以通过使用 SET 语句附加到数据库变量中来逐段提供。
      有关详细信息,请参见
      发送和检索 Long 型值

    • DT_TIMESTAMP_STRUCT    SQLDATETIME 结构,对于时间戳的每一部分都有一个字段。typedef struct sqldatetime {
         unsigned short year; /* e.g. 1999 */
         unsigned char month; /* 0-11 */
         unsigned char day_of_week; /* 0-6 0=Sunday */
         unsigned short day_of_year; /* 0-365 */
         unsigned char day; /* 1-31 */
         unsigned char hour; /* 0-23 */
         unsigned char minute; /* 0-59 */
         unsigned char second; /* 0-59 */
         unsigned long microsecond; /* 0-999999 */
      } SQLDATETIME;
      SQLDATETIME 结构可用于检索 DATE、TIME 和 TIMESTAMP 类型(或者可转换为这些类型之一的任意类型)的字段。应用程序常常具有它们自己的格式和日期操作代码。从该结构中读取数据使编程人员可以更轻松地操作该数据。注意,您也可以使用任何字符类型来读取和更新 DATE、TIME 和 TIMESTAMP 字段。
      如果您使用 SQLDATETIME 结构将日期、时间或时间戳输入到数据库中,则会忽略 day_of_year 和 day_of_week 成员。
      有关详细信息,请参见
      数据库选项
      中的 DATE_FORMAT、TIME_FORMAT、TIMESTAMP_FORMAT 和 DATE_ORDER 数据库选项。

    • DT_VARIABLE    以空值终止的字符串。字符串必须是 SQL 变量的名称,数据库服务器使用该变量的值。此数据类型仅用于为数据库服务器提供数据。在从数据库服务器读取数据时,不能使用它。

    这些结构在 sqlca.h 文件中定义。VARCHAR、BINARY 和 DECIMAL 类型包含一个单字符数组,因此,它们对于声明主机变量没有用,但是,对于动态分配变量或强制转换其它变量的类型有用。
    DATE 和 TIME 数据库类型
    对于各种不同的 DATE 和 TIME 数据库类型,没有对应的嵌入式 SQL 接口数据类型。这些数据库类型都是使用 SQLDATETIME 结构或字符串读取和更新的。
    有关详细信息,请参见
    GET DATA 语句 [ESQL]

    SET 语句

    使用主机变量
    主机变量是供 SQL 预处理器识别的 C 语言变量。主机变量可用于将值发送到数据库服务器或从数据库服务器接收值。
    主机变量非常易于使用,但是它们具有一些限制。动态 SQL 是一种向数据库服务器和从数据库服务器中传递信息的更常用的方法,它使用被称为 [SQL 描述符区域](SQLDA) 的结构。SQL 预处理器为使用主机变量的每个语句自动生成 SQLDA。
    有关动态 SQL 的信息,请参见
    静态和动态 SQL

    声明主机变量
    主机变量是通过将它们放入声明部分来定义的。按照 IBM SAA 和 ANSI 嵌入式 SQL 标准,主机变量是通过用以下内容围绕常规 C 变量声明定义的:
    EXEC SQL BEGIN DECLARE SECTION;
    /* C variable declarations */
    EXEC SQL END DECLARE SECTION;
    然后,可以使用这些主机变量代替任意 SQL 语句中的值常量。在数据库服务器执行命令时,会使用主机变量的值。注意,不能使用主机变量代替表名或列名:这需要使用动态 SQL。在 SQL 语句中,变量名以冒号 (:) 为前缀,以便与语句中使用的其它标识符区别开。
    标准 SQL 预处理器不扫描位于 DECLARE SECTION 之外的 C 语言代码。因此,不允许使用 TYPEDEF 类型和结构。在 DECLARE SECTION 内允许使用变量中的初始化程序。
    示例


    • 下面的示例代码阐释了主机变量在 INSERT 命令上是如何使用的。这些变量由程序填充,然后插入到数据库中:
      EXEC SQL BEGIN DECLARE SECTION;
      long employee_number;
      char employee_name[50];
      char employee_initials[8];
      char employee_phone[15];
      EXEC SQL END DECLARE SECTION;
      /* program fills in variables with appropriate values
      */
      EXEC SQL INSERT INTO Employee
      VALUES (:employee_number, :employee_name,
      :employee_initials, :employee_phone );
      有关更广泛的示例,请参见
      静态游标示例

    C 主机变量类型
    仅有有限数量的 C 数据类型可作为主机变量。而且,某些主机变量类型没有对应的 C 类型。
    可以使用在 sqlca.h 头文件中定义的宏声明以下类型的主机变量:VARCHAR、FIXCHAR、BINARY、PACKED DECIMAL、LONG VARCHAR、LONG BINARY 或 SQLDATETIME 结构。它们的使用方法如下所示:
    EXEC SQL BEGIN DECLARE SECTION;
    DECL_VARCHAR( 10 ) v_varchar;
    DECL_FIXCHAR( 10 ) v_fixchar;
    DECL_LONGVARCHAR( 32678 ) v_longvarchar;
    DECL_BINARY( 4000 ) v_binary;
    DECL_LONGBINARY( 128000 ) v_longbinary;
    DECL_DECIMAL( 10, 2 ) v_packed_decimal;
    DECL_DATETIME v_datetime;
    EXEC SQL END DECLARE SECTION;
    预处理器能够识别声明部分中的这些宏,并可将变量作为适当的类型对待。
    下表列出了允许用于主机变量的 C 变量类型及其对应的嵌入式 SQL 接口数据类型。
    C 数据类型
    嵌入式 SQL 接口类型
    说明
    short i;
    short int i;
    unsigned short int i;
    DT_SMALLINT
    16 位有符号的整数。
    long l;
    long int l;
    unsigned long int l;
    DT_INT
    32 位有符号的整数。
    float f;
    DT_FLOAT
    4 字节浮点数。
    double d;
    DT_DOUBLE
    8 字节浮点数。
    DECL_DECIMAL(p,s)
    DT_DECIMAL(p,s)
    压缩十进制数。
    char a; /*n=1*/
    DECL_FIXCHAR(n) a;
    DECL_FIXCHAR a[n];
    DT_FIXCHAR(n)
    填补空白的定长字符串。
    char a[n]; /*n>=1*/
    DT_STRING(n)
    以空值终止的字符串。如果数据库是使用填补空白的字符串进行的初始化,则该字符串是填补空白的。
    char *a;
    DT_STRING(32767)
    以空值终止的字符串。
    DECL_VARCHAR(n) a;
    DT_VARCHAR(n)
    具有 2 字节长度字段的变长字符串。不是填补空白的。
    DECL_BINARY(n) a;
    DT_BINARY(n)
    具有长度为 2 个字节的字段的变长二进制数据。
    DECL_DATETIME a;
    DT_TIMESTAMP_STRUCT
    SQLDATETIME 结构。
    DECL_LONGVARCHAR( n ) a;
    DT_LONGVARCHAR
    具有三个长度为 4 个字节的字段的长型变长字符串。不是填补空白的或以空值终止的。
    DECL_LONGBINARY( n ) a;
    DT_LONGBINARY
    具有三个长度为 4 个字节的字段的长型变长二进制数据。不是填补空白的。
    字符指针
    一个声明为字符 (char *a) 的主机变量会被数据库接口认为是 32767 字节长。任何字符类型的用于从数据库检索信息的主机变量都必须指向一个缓冲区,该缓冲区的大小要足以容纳可能从数据库返回的任何值。
    这具有相当大的潜在危险,因为可能会有人更改数据库中列的定义,使列比编写程序时更大。这可能会导致随机内存损坏问题。如果您使用的是 16 位编译器,要求 32767 字节可能会使程序堆栈溢出。使用声明数组会比较好,甚至是作为函数的参数,其中数组是作为字符传递的。这样就可以让 PREPARE 语句知道数组的大小。
    主机变量的范围
    标准主机变量声明部分可以出现在通常声明 C 变量的任意位置,包括 C 函数的参数声明部分。C 语言变量有其常规作用域(在定义它们的块中可用)。但是,因为 SQL 预处理器不扫描 C 代码,所以它与 C 语言块无关。
    就 SQL 预处理器而言,主机变量是全局的;两个主机变量不能同名。
    主机变量的用法
    主机变量可用于以下环境中:


    • 位于任何允许使用数字或字符串常量的位置的 SELECT、INSERT、UPDATE 和 DELETE 语句。

    • SELECT和 FETCH 语句的 INTO 子句。

    • 主机变量也可用来代替语句名、游标名或嵌入式 SQL 特定命令中的选项名。

    • 对于 CONNECT、DISCONNECT 和 SET CONNECT,可以用主机变量代替用户 ID、口令、连接名、连接字符串或数据库环境名。

    • 对于 SET OPTION 和 GET OPTION,可以用主机变量代替用户 ID、选项名或选项值。

    • 不能用主机变量代替任何语句中的表名或列名。

    示例


    • 下面是有效的嵌入式 SQL:
      INCLUDE SQLCA;
      long SQLCODE;
      sub1() {
         char SQLSTATE[6];
         exec SQL CREATE TABLE ...
      }

    • 下面是无效的嵌入式 SQL:
      INCLUDE SQLCA;
      sub1() {
         char SQLSTATE[6];
         exec SQL CREATE TABLE...
      }
      sub2() {
         exec SQL DROP TABLE...
         // No SQLSTATE in scope of this statement
      }

    • SQLSTATE 和 SQLCODE 的大小写是很重要的,ISO/ANSI 标准要求其定义必须与如下所示完全相同:
      long SQLCODE;
      char SQLSTATE[6];

    指示符变量
    指示符变量是在您读取或保存数据时存放补充信息的 C 变量。指示符变量有以下几种不同的用法:


    • NULL 值    使应用程序可以处理 NULL 值。

    • 字符串截断    使应用程序可以处理必须截断读取值以适合主机变量的情况。

    • 转换错误    保存错误消息。

    指示符变量是在 SQL 语句中紧跟常规主机变量放置的 short int 类型的主机变量。例如,在下面的 INSERT 语句中,:ind_phone 是一个指示符变量:
    EXEC SQL INSERT INTO Employee
       VALUES (:employee_number, :employee_name,
       :employee_initials, :employee_phone:ind_phone );
    使用指示符变量处理 NULL
    在 SQL 数据中,NULL 代表未知的属性或不适用的信息。不要将 SQL 中 NULL 的概念与 C 语言中具有这一名称 (NULL) 的常量混淆。C 常量用于代表非初始化的或无效的指针。
    在 Adaptive Server Anywhere 文档中使用 NULL 时,它指的是以上给出的 SQL 数据库的含义。该 C 语言常量称为 null 指针(小写)。
    NULL 不同于列的已定义类型的任何值。因此,为了将 NULL 值传递到数据库或接回 NULL 结果,除了常规主机变量外还需要其它条件。指示符变量正是用于此目的。
    插入 NULL 时使用指示符变量
    INSERT 语句可以包括一个指示符变量,如下所示:
    EXEC SQL BEGIN DECLARE SECTION;
    short int employee_number;
    char employee_name[50];
    char employee_initials[6];
    char employee_phone[15];
    short int ind_phone;
    EXEC SQL END DECLARE SECTION;/*
    program fills in empnum, empname,
    initials and homephone
    */
    if( /* phone number is unknown */ ) {
       ind_phone = -1;
    } else {
       ind_phone = 0;
    }
    EXEC SQL INSERT INTO Employee
       VALUES (:employee_number, :employee_name,
       :employee_initials, :employee_phone:ind_phone );
    如果指示符变量具有值 –1,则写入 NULL。如果它具有值 0,则写入 employee_phone 的实际值。
    在读取 NULL 时使用指示符变量
    从数据库中接收数据时也可使用指示符变量。它们用于指示读取了 NULL 值(指示符为负数)。如果从数据库中读取了 NULL 值,而又没有提供指示符变量,就会生成错误 (SQLE_NO_INDICATOR)。下一节将介绍错误。
    将指示符变量用于截断值
    指示符变量指示某些读取值是否为适合主机变量而被截断了。这使应用程序可以正确地处理截断问题。
    如果一个值在读取时被截断,则指示符变量会被设为正值,其中包含了在被截断前数据库值的实际长度。如果值的长度大于 32767,则指示符变量值为 32767。
    将指示符变量用于转换错误
    缺省情况下,CONVERSION_ERROR 数据库选项设置为 ON,任何数据类型转换失败都将导致一个错误,且不返回行。
    您可以使用指示符变量来标明哪个列导致了数据类型转换失败。如果您将数据库选项 CONVERSION_ERROR 设置为 OFF,则任何数据类型转换失败都将给出 CANNOT_CONVERT 警告,而不是错误。如果遇到转换错误的列具有一个指示符变量,则将该变量的值设置为 –2。
    如果您在向数据库中插入数据时将 CONVERSION_ERROR 选项设置为 OFF,则发生转换失败时就会插入 NULL 值。
    指示符变量值汇总
    下表提供指示符变量用法的摘要。
    指示符的值
    向数据库提供值
    从数据库接收值
    > 0
    主机变量的值
    检索的值被截断——指示符变量中的实际长度
    0
    主机变量的值
    读取成功,或 CONVERSION_ERROR 设置为 ON
    –1
    NULL 值
    NULL 结果
    –2
    NULL 值
    转换错误(仅当 CONVERSION_ERROR 设置为 OFF 时)。SQLCODE 指示一个 CANNOT_CONVERT 警告
    NULL 值
    NULL 结果
    有关检索 Long 型值的详细信息,请参见
    GET DATA 语句 [ESQL]

    SQL 通信区域 (SQLCA)
    SQL 通信区域(SQLCA) 是一个存储区域,将统计和错误从应用程序传递到数据库服务器再传回应用程序的每个数据库请求会使用它。SQLCA 用作应用程序到数据库的通信链接的句柄。它会被传递到需要与数据库服务器进行通信的所有数据库库函数中。它会在所有嵌入式 SQL 语句上被隐式传递。
    全局 SQLCA 变量在接口库中定义。预处理器会为全局 SQLCA 变量生成外部引用,并且会为该变量的指针生成外部引用。该外部引用名为 sqlca,类型为 SQLCA。指针名为 sqlcaptr。实际的全局变量在导入库中声明。
    SQLCA 由 sqlca.h 头文件定义,该文件包括在安装目录的 h 子目录中。
    SQLCA 提供错误代码
    可引用 SQLCA 测试特定错误代码。当数据库请求有错误时(见下文),sqlcodesqlstate 字段包含错误代码。某些 C 宏是为引用 sqlcode 字段、sqlstate 字段和某些其它字段而定义的。
    SQLCA 字段
    SQLCA 中的字段具有以下含义:


    • sqlcaid    8 字节字符字段,包含作为 SQLCA 结构标识的字符串 SQLCA。在您查看内存内容时,该字段可帮助进行调试。

    • sqlcabc    包含 SQLCA 结构的长度(136 字节)的长型整数。

    • sqlcode    数据库在请求上检测到错误时,指定错误代码的长整数。错误代码的定义可在头文件 sqlerr.h 中找到。成功操作的错误代码是 0(零),正数表示警告,负数表示错误。
      有关错误代码的完整列表,请参见
      ASA 错误消息

    • sqlerrml    sqlerrmc 字段中信息的长度。

    • sqlerrmc    要插入到错误消息中的零个或多个字符串。某些错误消息包含一个或多个占位字符串(%1%2、...),这些占位字符串可替换为此字段中的字符串。
      例如,如果生成未找到表错误,则 sqlerrmc 包含表名,该表名要插入到错误消息中的适当位置。
      有关错误消息的完整列表,请参见
      ASA 错误消息

    • sqlerrp    保留。

    • sqlerrd    长整数的实用程序数组。

    • sqlwarn    保留。

    • sqlstate    SQLSTATE 状态值。除了以前标准中的 SQLCODE 值外,ANSI SQL 标准 (SQL-92) 还定义了 SQL 语句的一种新类型的返回值。SQLSTATE 值始终是一个由五个字符组成且以空值终止的字符串,它分为双字符类(前两个字符)和三字符子类。每个字符都可以是从 0 到 9 的数字或从 A 到 Z 的大写字母字符。
      以 0 到 4 或 A 到 H 开头的任何类或子类都是由 SQL 标准定义的,其它类和子类则是各实现自行定义的。SQLSTATE 值 '00000' 表示还没有错误或警告。
      有关更多的 SQLSTATE 值,请参见
      ASA 错误消息

    sqlerror 数组
    sqlerror 字段数组具有以下元素。


    • sqlerrd[1] (SQLIOCOUNT)    完成命令所需的实际输入/输出操作数。
      数据库执行每个命令之前不会清零。在执行一个命令序列之前,您的程序可以将此变量设置为零。在最后一个命令执行之后,此数字是整个命令序列的输入/输出操作的总数。

    • sqlerrd[2] (SQLCOUNT)    此字段的值取决于要执行的语句。


      • INSERT、UPDATE、PUT 和 DELETE 语句    受语句影响的行数。
        在游标 OPEN 上,该字段由游标中的实际行数(大于或等于 0 的值)或它的估计数(绝对值是估计数的负数)填充。如果数据库服务器不统计该值即可计算出行数,则该值就是实际行数。也可以使用 ROW_COUNT 选项,将数据库配置为始终返回实际的行数。

      • FETCH 游标语句    如果返回 SQLE_NOTFOUND 警告,则填充 SQLCOUNT 字段。它包含 FETCH RELATIVE 或 FETCH ABSOLUTE 语句超出可能的游标位置(游标可以位于某一行上、第一行之前或最后一行之后)范围之外的行数。在宽读取的情况下,SQLCOUNT 是实际读取的行数,它小于或等于请求的行数。在宽读取过程中, 设置 SQLE_NOTFOUND。
        有关宽读取的详细信息,请参见
        一次读取多个行

        如果未找到行但位置有效,则值为 0,例如,当定位在游标的最后一行上时执行 FETCH RELATIVE 1。如果所尝试的读取超出了游标的末尾,则为正值;如果所尝试的读取位于游标开头的前面,则为负值。

      • GET DATA 语句    SQLCOUNT 字段保存值的实际长度。

      • DESCRIBE 语句    在用于说明可能具有多个结果集的过程的 WITH VARIABLE RESULT 子句中,SQLCOUNT 设置为以下值之一:


        • 0    结果集可能会有变化:在每个 OPEN 语句之后应再次说明过程调用。

        • 1    结果集是固定的。不需要再次进行说明。

        在出现语法错误 SQLE_SYNTAX_ERROR 的情况下,此字段包含命令字符串内检测到错误的大致字符位置。

    • sqlerrd[3] (SQLIOESTIMATE)    完成命令所需的输入/输出操作的估计数。在 OPEN 或 EXPLAIN 命令上将给此字段赋一个值。

    多线程代码或再入式代码的 SQLCA 管理
    您可以在多线程代码或再入式代码中使用嵌入式 SQL 语句。但是,如果您使用单个连接,则对于每个连接您只能有一个活动请求。在多线程应用程序中,除非使用信号控制访问,否则在每个线程上不应使用到数据库的同一连接。
    对于在希望使用数据库的每个线程上使用单独的连接没有限制。运行时库使用 SQLCA 来区分不同的线程上下文。因此,希望使用数据库的每个线程都必须具有它自己的 SQLCA。
    任何给定的数据库连接都只能从一个 SQLCA 访问,但取消指令除外,此指令必须从单独的线程发出。
    有关取消请求的信息,请参见
    实现请求管理

    使用多个 SQLCA
    在您的应用程序中管理多个 SQLCA

  • 您必须在 SQL 预处理器上使用生成再入式代码的选项 (-r)。由于无法使用静态初始化的全局变量,因此再入式代码稍大且速度稍慢。不过,这些影响是很小的。

  • 在程序中使用的每个 SQLCA 都必须调用 db_init 进行初始化,并在结尾处调用 db_fini 清除它。
    注意    对于 NetWare 上的每个 db_init,如果未能调用 db_fini,则会导致数据库服务器和 NetWare 文件服务器出现故障。

  • 嵌入式 SQL 语句 SET SQLCA(
    SET SQLCA 语句 [ESQL]
    )用于通知 SQL 预处理器对于数据库请求使用不同的 SQLCA。在程序顶部或头文件中,通常会使用类似 EXEC SQL SET SQLCA 'task_data->sqlca'; 这样的一条语句,将 SQLCA 引用设置为指向任务特定的数据。此语句不生成任何代码,因而不影响性能。它更改预处理器内的状态,以便对 SQLCA 的任何引用都使用给定的字符串。
    有关创建 SQLCA 的信息,请参见
    SET SQLCA 语句 [ESQL]

    何时使用多个 SQLCA
    您可以在任一受支持的嵌入式 SQL 环境中使用多个 SQLCA 支持,但仅在再入式代码中要求这样做。
    下面的列表详细说明必须使用多个 SQLCA 的环境:


    • 多线程应用程序    如果多个线程使用同一 SQLCA,上下文切换会导致多个线程同时使用该 SQLCA。每个线程都必须具有它自己的 SQLCA。当 DLL 使用嵌入式 SQL 且被应用程序中的多个线程调用时,也会发生这种情况。

    • 动态链接库和共享库    DLL 只有一个数据段。数据库服务器在处理一个应用程序发出的请求时,也可能会优先处理另一个应用程序向该数据库服务器发出的请求。如果您的 DLL 使用全局 SQLCA,则这两个应用程序会同时使用它。每个 Windows 应用程序都必须具有它自己的 SQLCA。

    • 具有一个数据段的 DLL    可以将 DLL 创建为只有一个数据段,或者对于每个应用程序有一个数据段。如果您的 DLL 只有一个数据段,则无法使用全局 SQLCA,其原因与 DLL 无法使用全局 SQLCA 的原因相同。每个应用程序必须具有它自己的 SQLCA。

    用多个 SQLCA 进行连接管理
    您无需使用多个 SQLCA 以连接到多个数据库或具有到单个数据库的多个连接。
    每个 SQLCA 都可以具有一个未命名的连接。每个 SQLCA 都具有一个活动的或当前的连接(请参见
    SET CONNECTION 语句 [Interactive SQL] [ESQL]
    )。在所给定数据库连接上进行的所有操作都必须使用建立数据库连接时所使用的同一个 SQLCA。
    记录锁定 不同连接上的操作受常规记录锁定机制的影响,并且可能导致互相阻塞,甚至可能导致死锁。有关锁定的信息,请参见
    使用事务和隔离级别
    一章。
    读取数据
    读取嵌入式 SQL 中的数据是通过使用 SELECT 语句来完成的。这包括两种情况:

    LONG VARCHAR 和 LONG BINARY 数据类型的处理方式与其它数据类型不同。有关详细信息,请参见
    检索 LONG 数据

    最多返回一行的 SELECT 语句
    单行查询最多从数据库中检索一行。单行查询 SELECT 语句在选择列表之后和 FROM 子句之前有一个 INTO 子句。INTO 子句包含一个主机变量的列表,用来接收每个选择列表项的值。主机变量和选择列表项的数目必须相同。主机变量可以和指示符变量一起使用,以指示 NULL 结果。
    当执行 SELECT 语句时,数据库服务器检索结果并将其放在主机变量中。如果查询结果包含多个行,则数据库服务器会返回一个错误。
    如果查询结果中没有选定的行,则返回 [未找到行] 警告。在 SQLCA 结构中返回错误和警告(如
    SQL 通信区域 (SQLCA)
    中所述)。
    示例
    例如,如果成功地从 employee 表读取了一行,则以下代码段返回 1;如果该行不存在则返回 0;如果出现错误则返回 –1。
    EXEC SQL BEGIN DECLARE SECTION;
       long         emp_id;
       char         name[41];
       char         sex;
       char         birthdate[15];
       short int   ind_birthdate;
    EXEC SQL END DECLARE SECTION;
    . . .
    int find_employee( long employee )
    {
       emp_id = employee;
       EXEC SQL   SELECT emp_fname ||
                ' ' || emp_lname, sex, birth_date
                INTO :name, :sex,
                      :birthdate:ind_birthdate
                FROM "DBA".employee
                WHERE emp_id = :emp_id;
       if( SQLCODE == SQLE_NOTFOUND ) {
          return( 0 ); /* employee not found */
       } else if( SQLCODE
    在嵌入式 SQL 中使用游标
    游标用于从其结果集中具有多个行的查询中检索行。游标是 SQL 查询的句柄或标识符和结果集中的一个位置。
    有关游标的介绍,请参见
    使用游标

    在嵌入式 SQL 中管理游标:

  • 使用 DECLARE 语句声明特定 SELECT 语句的游标。

  • 使用 OPEN 语句打开游标。

  • 使用 FETCH 语句一次一行地从游标中检索结果。

  • 读取行,直到返回 [未找到行] 警告。
    在 SQLCA 结构中返回错误和警告(如
    SQL 通信区域 (SQLCA)
    中所述)。

  • 使用 CLOSE 语句关闭游标。
    缺省情况下,在事务(COMMIT 或 ROLLBACK 上)的结尾会自动关闭游标。用 WITH HOLD 子句打开的游标对于后续事务保持打开状态,直到它们被显式关闭。
    以下是游标用法的简单示例:
    void print_employees( void )
    {
       EXEC SQL BEGIN DECLARE SECTION;
       char name[50];
       char sex;
       char birthdate[15];
       short int ind_birthdate;
       EXEC SQL END DECLARE SECTION;
       EXEC SQL DECLARE C1 CURSOR FOR
          SELECT   emp_fname || ' ' || emp_lname,
                   sex, birth_date
          FROM "DBA".employee;
       EXEC SQL OPEN C1;
       for( ;; ) {
          EXEC SQL FETCH C1 INTO :name, :sex,
            :birthdate:ind_birthdate;
          if( SQLCODE == SQLE_NOTFOUND ) {
             break;
          } else if( SQLCODE
    有关使用游标的完整示例,请参见
    静态游标示例

    动态游标示例

    游标定位
    游标定位在以下三个位置之一:


    • 在一行上

    • 在第一行之前

    • 在最后一行之后



    当游标打开之后,它位于结果集的第一行之前。使用 FETCH 命令可移动游标位置(请参见
    FETCH 语句 [ESQL] [SP]
    )。可以将游标定位到相对查询结果开头或结尾的一个绝对位置。也可以相对当前游标位置移动它。
    UPDATE 和 DELETE 语句有特殊的定位 版本,可用于更新或删除游标当前位置处的行。如果游标位于第一行之前或最后一行之后,那么将返回 [没有当前的游标行] 错误。
    可以使用 PUT 语句向游标中插入行。
    游标定位问题
    插入 DYNAMIC SCROLL 游标并对其进行某些更新会导致与游标定位有关的问题。除非 SELECT 语句中有 ORDER BY 子句,否则数据库服务器不将插入的行放在游标内可预知的位置。在有些情况下,插入的行要等到关闭并再次打开游标后才会出现。
    对于 Adaptive Server Anywhere,如果必须创建临时表才能打开游标,则会出现这种情况。
    有关说明,请参见
    在查询处理中使用工作表

    UPDATE 语句可能导致行在游标中移动。如果游标具有一个使用现有索引(未创建临时表)的 ORDER BY 子句,则会出现这种情况。
    一次读取多个行
    可以将 FETCH 语句修改为一次读取多行,这样可能会改善性能。这种方式被称为宽读取数组读取
    Adaptive Server Anywhere 还支持宽放置和宽插入。有关这些内容的详细信息,请参见
    PUT 语句 [ESQL]

    EXECUTE 语句 [ESQL]

    要在嵌入式 SQL 中使用宽读取,请将 fetch 语句包括在代码中,如下所示:
    EXEC SQL FETCH . . . ARRAY nnn
    其中 ARRAY nnn 是 FETCH 语句的最后一项。读取计数 nnn 可以是一个主机变量。SQLDA 中的变量数必须是 nnn 和每行的列数的乘积。第一行放在 SQLDA 变量 0 到(每行的列数)–1 中,以此类推。
    SQLDA 的每一行中的每一列的类型必须相同,否则会返回 SQLDA_INCONSISTENT 错误。
    服务器在 SQLCOUNT 中返回读取的记录数,除非有错误或警告,否则该记录数始终大于零。在宽读取时,在没有错误的情况下,SQLCOUNT 为一 (1) 指示已经读取一个有效行。
    示例
    下面的示例代码说明如何使用宽读取。您也可以在 SQL Anywhere 目录的 samples/ASA/esqlwidefetch/widefetch.sqc 中找到此代码。
    #include
    #include
    #include
    #include "sqldef.h"
    EXEC SQL INCLUDE SQLCA;
    EXEC SQL WHENEVER SQLERROR { PrintSQLError();
                  goto err; };
    static void PrintSQLError()
    /*************************/
    {
        char buffer[200];
        printf( "SQL error %d -- %s/n",
           SQLCODE,
           sqlerror_message( &sqlca,
                   buffer,
                   sizeof( buffer ) ) );
    }static SQLDA * PrepareSQLDA(
       a_sql_statement_number   stat0,
       unsigned      width,
       unsigned      *cols_per_row )
    /*********************************************/
    /* Allocate a SQLDA to be used for fetching from
       the statement identified by "stat0". "width"
       rows will be retrieved on each FETCH request.
       The number of columns per row is assigned to
       "cols_per_row". */
    {
        int                     num_cols;
        unsigned                row, col, offset;
        SQLDA *                 sqlda;
        EXEC SQL BEGIN DECLARE SECTION;
        a_sql_statement_number  stat;
        EXEC SQL END DECLARE SECTION;    stat = stat0;
        sqlda = alloc_sqlda( 100 );
        if( sqlda == NULL ) return( NULL );
        EXEC SQL DESCRIBE :stat INTO sqlda;
        *cols_per_row = num_cols = sqlda->sqld;
        if( num_cols * width > sqlda->sqln ) {
            free_sqlda( sqlda );
            sqlda = alloc_sqlda( num_cols * width );
            if( sqlda == NULL ) return( NULL );
            EXEC SQL DESCRIBE :stat INTO sqlda;
        }    // copy first row in SQLDA setup by describe
        // to following (wide) rows
        sqlda->sqld = num_cols * width;
        offset = num_cols;
        for( row = 1; row sqlvar[offset].sqltype =
                      sqlda->sqlvar[col].sqltype;
                sqlda->sqlvar[offset].sqllen =
                     sqlda->sqlvar[col].sqllen;
           // optional: copy described column name
                memcpy( &sqlda->sqlvar[offset].sqlname,
                        &sqlda->sqlvar[col].sqlname,
                        sizeof( sqlda->sqlvar[0].sqlname ) );
            }
        }
        fill_s_sqlda( sqlda, 40 );
        return( sqlda );err:
        return( NULL );
    }static void PrintFetchedRows( SQLDA * sqlda,
                   unsigned cols_per_row )
    /******************************************/
    /* Print rows already wide fetched in the SQLDA */
    {
        long                    rows_fetched;
        int             row, col, offset;
        if( SQLCOUNT == 0 ) {
           rows_fetched = 1;
        } else {
             rows_fetched = SQLCOUNT;
        }
        printf( "Fetched %d Rows:/n", rows_fetched );
        for( row = 0; row sqlvar[offset]
                   .sqldata );
             }
             printf( "/n" );
        }
    }static int DoQuery( char * query_str0,
                   unsigned fetch_width0 )
    /*****************************************/
    /* Wide Fetch "query_str0" select statement
    * using a width of "fetch_width0" rows" */
    {
        SQLDA *                 sqlda;
        unsigned          cols_per_row;
        EXEC SQL BEGIN DECLARE SECTION;
        a_sql_statement_number  stat;
        char *          query_str;
        unsigned          fetch_width;
        EXEC SQL END DECLARE SECTION;
        query_str = query_str0;
        fetch_width = fetch_width0;
        EXEC SQL PREPARE :stat FROM :query_str;
        EXEC SQL DECLARE QCURSOR CURSOR FOR :stat
               FOR READ ONLY;
        EXEC SQL OPEN QCURSOR;
        sqlda = PrepareSQLDA( stat,
               fetch_width,
               &cols_per_row );
        if( sqlda == NULL ) {
            printf( "Error allocating SQLDA/n" );
            return( SQLE_NO_MEMORY );
        }    for( ;; ) {
            EXEC SQL FETCH QCURSOR INTO DESCRIPTOR sqlda
               ARRAY :fetch_width;
            if( SQLCODE != SQLE_NOERROR ) break;
                PrintFetchedRows( sqlda, cols_per_row );
        }
        EXEC SQL CLOSE QCURSOR;
        EXEC SQL DROP STATEMENT :stat;
        free_filled_sqlda( sqlda );
    err:
        return( SQLCODE );
    }void main( int argc, char *argv[] )
    /*********************************/
    /* Optional first argument is a select statement,
    * optional second argument is the fetch width */
    {
        char *query_str =
         "select emp_fname, emp_lname from employee";
        unsigned fetch_width = 10;
        if( argc > 1 ) {
            query_str = argv[1];
            if( argc > 2 ) {
              fetch_width = atoi( argv[2] );
              if( fetch_width
    有关使用宽读取的注意事项


    • 在函数 PrepareSQLDA 中,SQLDA 内存是使用 alloc_sqlda 函数分配的。这样就为指示符变量留出了空间,而不用使用 alloc_sqlda_noind 函数。

    • 如果读取的行数小于请求的行数,但又不是零(例如在游标的末尾),则通过设置指示符值可将对应于未读取的行的 SQLDA 项作为 NULL 返回。如果不存在指示符变量,则生成一个错误(SQLE_NO_INDICATOR:NULL 结果没有指示符变量)。

    • 如果正在读取的行已经更新,并且生成了 SQLE_ROW_UPDATED_WARNING 警告,那么,读取到导致警告的行时就会停止。将返回处理到该点的所有行(包括导致警告的行)的值。SQLCOUNT 包含读取的行数,其中包括导致警告的行。所有剩余的 SQLDA 项都被标记为 NULL。

    • 如果正在读取的行已经被删除或锁定,并且生成了 SQLE_NO_CURRENT_ROW 或 SQLE_LOCKED 错误,则 SQLCOUNT 包含出错前读取的行数。这不包括导致错误的行。SQLDA 不包含任何行的值,因为出现错误时不返回 SQLDA 值。如果必要,可使用 SQLCOUNT 值来重新定位游标,以便读取行。

    静态和动态 SQL
    有以下两种方式可以将 SQL 语句嵌入到 C 程序中:


    • 静态语句

    • 动态语句

    在此之前,我们一直在讨论静态 SQL。本节将对静态 SQL 和动态 SQL 进行比较。
    静态 SQL 语句
    通过在标准 SQL 数据操纵语句和数据定义语句之前加上 EXEC SQL 并在命令之后加上分号 (;),可以将所有这些语句嵌入到 C 程序中。这些语句称为静态语句。

    使用主机变量
    中所述,静态语句可以包含对主机变量的引用。此前的所有示例中使用的都是静态嵌入式 SQL 语句。
    主机变量只能用来代替字符串或数字常量,不能用来代替列名或表名;执行那些操作需要使用动态语句。
    动态 SQL 语句
    在 C 语言中,字符串存储在字符数组中。动态语句是用 C 语言字符串构造的。然后,可以使用 PREPARE 和 EXECUTE 语句执行这些语句。这些 SQL 语句无法按与静态语句相同的方式引用主机变量,因为在执行 C 程序时无法按名称访问 C 语言变量。
    要在语句和 C 语言变量之间传递信息,请使用名为 SQL 描述符区域 (SQLDA) 的数据结构。如果您在 EXECUTE 命令的 USING 子句中指定一组主机变量,则 SQL 预处理器会为您建立此结构。这些变量按位置对应于准备好的命令字符串相应位置中的占位符。
    有关 SQLDA 的信息,请参见
    SQL 描述符区域 (SQLDA)

    占位符放在语句中是为了指示要访问主机变量的位置。占位符可以是问号 (?),或者也可以是静态语句中的主机变量引用(主机变量名之前有一个冒号)。在后一种情况下,在语句的实际文本中使用的主机变量名仅充当占位符,指示对 SQL 描述符区域的引用。
    用于向数据库传递信息的主机变量称为绑定变量
    示例
    例如:
    EXEC SQL BEGIN DECLARE SECTION;
       char comm[200];
       char address[30];
       char city[20];
       short int cityind;
       long empnum;
    EXEC SQL END DECLARE SECTION;
    . . .
       sprintf( comm, "update %s set address = :?,
                         city = :?"
                " where employee_number = :?",
                tablename );
    EXEC SQL PREPARE S1 FROM :comm;
    EXEC SQL EXECUTE S1 USING :address, :city:cityind, :empnum;
    此方法要求程序员知道语句中共有多少个主机变量。但程序员对这一点往往并不清楚。所以,您可以建立您自己的 SQLDA 结构并在 EXECUTE 命令的 USING 子句中指定此 SQLDA。
    DESCRIBE BIND VARIABLES 语句返回在预准备语句中找到的绑定变量的主机变量名。这使 C 程序可以更容易地管理主机变量。一般的方法如下:
    EXEC SQL BEGIN DECLARE SECTION;
       char comm[200];
    EXEC SQL END DECLARE SECTION;
    . . .
    sprintf( comm, "update %s set address = :address,
              city = :city"
             " where employee_number = :empnum",
             tablename );
    EXEC SQL PREPARE S1 FROM :comm;
    /* Assume that there are no more than 10 host variables. See next example if you can't put
    a limit on it */
    sqlda = alloc_sqlda( 10 );
    EXEC SQL DESCRIBE BIND VARIABLES FOR S1 USING DESCRIPTOR sqlda;
    /* sqlda->sqld will tell you how many host variables there were. */
    /* Fill in SQLDA_VARIABLE fields with values based on
    name fields in sqlda */
    . . .
    EXEC SQL EXECUTE S1 USING DESCRIPTOR sqlda;
    free_sqlda( sqlda );
    SQLDA 的内容
    SQLDA 包含一组变量描述符。每个描述符说明对应的 C 程序变量的属性或者数据库存储数据的位置或检索数据的位置:


    • 数据类型

    • 如果 type 是字符串类型,则为长度

    • 如果 type 是数字类型,则为精度和小数位数

    • 内存地址

    • 指示符变量

    有关 SQLDA 结构的完整说明,请参见
    SQL 描述符区域 (SQLDA)
    指示符变量和 NULL
    指示符变量用于将 NULL 值传递到数据库或从数据库检索 NULL 值。指示符变量还由数据库服务器用来指示在数据库操作过程中遇到的截断条件。当提供的空间不足,无法接收数据库值时,会将指示符变量设置为正值。
    有关详细信息,请参见
    指示符变量

    动态 SELECT 语句
    可以动态准备仅返回单个行的 SELECT 语句,后跟带 INTO 子句的 EXECUTE 以检索单行结果。但是,返回多个行的 SELECT 语句是使用动态游标管理的。
    使用动态游标时,将结果放在 FETCH 语句(FETCH INTO 和 FETCH USING DESCRIPTOR)中指定的主机变量列表或 SQLDA 中。由于 C 程序员通常不知道选择列表项数,因此最常使用 SQLDA。DESCRIBE SELECT LIST 语句建立具有选择列表项的类型的 SQLDA。然后,使用 fill_sqlda() 函数为这些值分配空间,由 FETCH USING DESCRIPTOR 语句检索信息。
    典型的情况如下:
    EXEC SQL BEGIN DECLARE SECTION;
       char comm[200];
    EXEC SQL END DECLARE SECTION;
       int actual_size;
       SQLDA * sqlda;
    . . .
    sprintf( comm, "select * from %s", table_name );
    EXEC SQL PREPARE S1 FROM :comm;
    /* Initial guess of 10 columns in result. If it is
       wrong, it is corrected right after the first
       DESCRIBE by reallocating sqlda and doing DESCRIBE    again. */
    sqlda = alloc_sqlda( 10 );
    EXEC SQL DESCRIBE SELECT LIST FOR S1 USING DESCRIPTOR sqlda;
    if( sqlda->sqld > sqlda->sqln ){
       actual_size = sqlda->sqld;
       free_sqlda( sqlda );
       sqlda = alloc_sqlda( actual_size );
       EXEC SQL DESCRIBE SELECT LIST FOR S1
          USING DESCRIPTOR sqlda;
    }
    fill_sqlda( sqlda );
    EXEC SQL DECLARE C1 CURSOR FOR S1;
    EXEC SQL OPEN C1;
    EXEC SQL WHENEVER NOTFOUND {break};
    for( ;; ){
       EXEC SQL FETCH C1 USING DESCRIPTOR sqlda;
       /* do something with data */
    }
    EXEC SQL CLOSE C1;
    EXEC SQL DROP STATEMENT S1;
    使用后删除语句 为避免占用不必要的资源,请确保在使用语句后将其删除。
    有关使用动态选择语句的游标的完整示例,请参见
    动态游标示例

    有关上述函数的详细信息,请参见
    库函数参考

    SQL 描述符区域 (SQLDA)
    SQLDA(SQL 描述符区域)是一个用于动态 SQL 语句的接口结构。此结构可将有关主机变量和 SELECT 语句结果的信息传入和传出数据库。SQLDA 在头文件 sqlda.h 中定义。
    数据库接口库或 DLL 中有可用于管理 SQLDA 的函数。有关说明,请参见
    库函数参考

    当主机变量与静态 SQL 语句一起使用时,预处理器会为那些主机变量构造 SQLDA。实际上,被传入传出数据库服务器的正是此 SQLDA。
    SQLDA 头文件
    sqlda.h 的内容如下:
    #ifndef _SQLDA_H_INCLUDED
    #define _SQLDA_H_INCLUDED
    #define II_SQLDA
    #include "sqlca.h"
    #if defined( _SQL_PACK_STRUCTURES )
    #include "pshpk1.h"
    #endif
    #define SQL_MAX_NAME_LEN  30
    #define _sqldafar
    typedef   short int   a_SQL_type;
    struct sqlname {
        short int length; /* length of char data */
        char      data[ SQL_MAX_NAME_LEN ]; /* data */
    };struct sqlvar {    /* array of variable descriptors   */
        short int  sqltype; /* type of  host variable    */
        short int   sqllen; /* length of host variable    */
        void      *sqldata; /* address of variable  */
        short int  *sqlind; /* indicator variable pointer */
        struct sqlname  sqlname;
    };struct sqlda{
        unsigned char  sqldaid[8]; /* eye catcher "SQLDA"*/
        a_SQL_int32  sqldabc; /* length of sqlda structure*/
        short int  sqln;
                 /* descriptor size in number of entries */
        short int  sqld;
                 /* number of variables found by DESCRIBE*/
        struct sqlvar       sqlvar[1];
                 /* array of variable descriptors */
    };#define SCALE(sqllen)           ((sqllen)/256)
    #define PRECISION(sqllen)       ((sqllen)&0xff)
    #define SET_PRECISION_SCALE(sqllen,precision,scale)     /
                              sqllen = (scale)*256 + (precision)
    #define DECIMALSTORAGE(sqllen)  (PRECISION(sqllen)/2 + 1)
    typedef struct sqlda    SQLDA;
    typedef struct sqlvar   SQLVAR, SQLDA_VARIABLE;
    typedef struct sqlname  SQLNAME, SQLDA_NAME;#ifndef SQLDASIZE
    #define SQLDASIZE(n)    ( sizeof( struct sqlda ) +  /
                              (n-1) * sizeof( struct sqlvar) )
    #endif
    #if defined( _SQL_PACK_STRUCTURES )
    #include "poppk.h"
    #endif
    #endif
    SQLDA 字段
    SQLDA 的各字段的含义如下:
    字段
    说明
    sqldaid
    8 字节字符字段,包含作为 SQLDA 结构标识的字符串 SQLDA。在您查看内存内容时,该字段可帮助进行调试。
    sqldabc
    包含 SQLDA 结构的长度的长型整数。
    sqln
    sqlvar 数组中包含的变量描述符数。
    sqld
    有效的变量描述符(包含说明主机变量的信息)的数目。在向数据库服务器提供数据时,此字段由 DESCRIBE 语句设置,在向数据库服务器提供数据时,有时由程序员设置。
    sqlvar
    一组类型为 struct sqlvar 的描述符,每个描述符描述一个主机变量。
    SQLDA 主机变量说明
    SQLDA 中的每个 sqlvar 结构都说明一个主机变量。sqlvar 结构的各字段的含义如下:


    • sqltype    此描述符描述的变量的类型(请参见
      嵌入式 SQL 数据类型
      )。
      低序位指示是否允许使用 NULL 值。有效的类型和常量定义可以在 sqldef.h 头文件中找到。
      此字段由 DESCRIBE 语句填充。在向数据库服务器提供数据或从中检索数据时,您可以将此字段设置为任何类型。任何必需的类型转换都会自动完成。

    • sqllen    变量的长度。该长度的实际含义取决于类型信息和 SQLDA 的使用方式。
      对于 DECIMAL 类型,此字段分为两个 1 字节字段。高字节是精度,低字节是小数位数。精度是总位数。小数位数是小数点之后的位数。
      对于 LONG VARCHAR 和 LONG BINARY 数据类型,使用 DT_LONGBINARY 和 DT_LONGVARCHAR 数据类型结构的 array_len 字段,而不是使用 sqllen 字段。
      有关此长度字段的详细信息,请参见
      SQLDA sqllen 字段值

    • sqldata    指向此变量所占用的内存的四字节指针。此内存必须对应于 sqltypesqllen 字段。
      有关存储格式,请参见
      嵌入式 SQL 数据类型

      对于 UPDATE 和 INSERT 命令,如果 sqldata 指针是空指针,操作中就不会涉及此变量。对于 FETCH,如果 sqldata 指针是空指针,则不返回数据。换句话说,sqldata 指针返回的列是未绑定列
      如果 DESCRIBE 语句使用 LONG NAMES,则此字段保存结果集列的长名称。另外,如果 DESCRIBE 语句是 DESCRIBE USER TYPES 语句,则此字段保存用户定义的数据类型的长名称,而不是列的长名称。如果该类型是基类型,则此字段为空。

    • sqlind    指向指示符值的指针。指示符值是 short int。负的指示符值表示是 NULL 值。正的指示符值表示此变量已经被 FETCH 语句截断,且指示符值包含截断前的数据长度。如果将 CONVERSION_ERROR 数据库选项设置为 OFF,则值 –2 表示出现了转换错误。
      有关详细信息,请参见
      指示符变量

      如果 sqlind 指针是空指针,则说明没有适用于此主机变量的指示符变量。
      DESCRIBE 语句也使用 sqlind 字段来指示参数类型。如果类型是用户定义的数据类型,则此字段将设置为 DT_HAS_USERTYPE_INFO。在这种情况下,您可能希望执行 DESCRIBE USER TYPES 以获得有关用户定义的数据类型的信息。

    • sqlname    类似 VARCHAR 的结构,如下所示:struct sqlname {
         short int  length;
         char      data[ SQL_MAX_NAME_LEN ];
      };
      它由 DESCRIBE 语句填充,在其它情况下不使用它。对于以下两种格式的 DESCRIBE 语句,此字段具有不同的含义:


      • SELECT LIST    名称缓冲区由选择列表中对应项的列标题填充。

      • BIND VARIABLES    名称缓冲区由曾用作绑定变量的主机变量的名称填充,或者,如果使用了未命名的参数标记,则用"?"填充。

      在 DESCRIBE SELECT LIST 命令中,出现的任何指示符变量都会用一个标志(指示选择列表项是否可更新)来填充。有关此标志的详细信息可以在 sqldef.h 头文件中找到。
      如果 DESCRIBE 语句是 DESCRIBE USER TYPES 语句,则此字段保存用户定义数据类型的长名称,而不是列的长名称。如果该类型是基类型,则此字段为空。

    SQLDA sqllen 字段值
    在 SQLDA 中,sqlvar 结构的 sqllen 字段长度在与数据库服务器进行以下种类的交互作用时使用:


    • 说明值    DESCRIBE 语句获取有关主机变量的信息(这些主机变量是存储从数据库检索的数据或将数据传递到数据库时所必需的)。
      请参见
      说明值

    • 检索值    从数据库检索值。
      请参见
      检索值

    • 发送值    向数据库发送信息。
      请参见
      发送值

    • 本节将讲述这些交互作用。

    下表逐一详细说明了这些交互作用。这些表列出在 sqldef.h 头文件中找到的接口常量类型(DT_ 类型)。这些常量应放在 SQLDA sqltype 字段中。
    有关 sqltype 字段值的信息,请参见
    嵌入式 SQL 数据类型

    在静态 SQL 中,也会使用 SQLDA,但它是由 SQL 预处理器生成并完全填充的。在这种静态情况下,这些表给出静态 C 语言主机变量类型和接口常量之间的对应关系。
    说明值
    下表为各种数据库类型指明由 DESCRIBE 命令返回的 sqllensqltype 结构成员的值(SELECT LIST 和 BIND VARIABLE DESCRIBE 语句)。在用户定义的数据库数据类型的情况下,则对基类型进行说明。
    您的程序可以使用从 DESCRIBE 返回的类型和长度,或者您可以使用另一种类型。数据库服务器在任意两种类型之间执行类型转换。由 sqldata 字段指向的内存必须对应于 sqltypesqllen 字段。
    有关嵌入式 SQL 数据类型的信息,请参见
    嵌入式 SQL 数据类型

    数据库字段类型
    返回的嵌入式 SQL 类型
    说明时返回的长度
    BIGINT
    DT_BIGINT
    8
    BINARY(n)
    DT_BINARY
    n
    BIT
    DT_BIT
    1
    CHAR(n)
    DT_FIXCHAR
    n
    DATE
    DT_DATE
    最长的带格式字符串的长度
    DECIMAL(p,s)
    DT_DECIMAL
    SQLDA 中长度字段的高字节设置为 p,低字节设置为 s
    DOUBLE
    DT_DOUBLE
    8
    FLOAT
    DT_FLOAT
    4
    INT
    DT_INT
    4
    LONG BINARY
    DT_LONGBINARY
    32767
    LONG VARCHAR
    DT_LONGVARCHAR
    32767
    REAL
    DT_FLOAT
    4
    SMALLINT
    DT_SMALLINT
    2
    TIME
    DT_TIME
    最长的带格式字符串的长度
    TIMESTAMP
    DT_TIMESTAMP
    最长的带格式字符串的长度
    TINYINT
    DT_TINYINT
    1
    UNSIGNED BIGINT
    DT_UNSBIGINT
    8
    UNSIGNED INT
    DT_UNSINT
    4
    UNSIGNED SMALLINT
    DT_UNSSMALLINT
    2
    VARCHAR(n)
    DT_VARCHAR
    n
    发送值
    下表指明当您向数据库服务器提供数据时指定 SQLDA 中值的长度的方式。
    在这种情况下,只允许使用表中显示的数据类型。在向数据库提供信息时,将 DT_DATE、DT_TIME 和 DT_TIMESTAMP 类型视为与 DT_STRING 相同;值必须是具有适当日期格式且以空值终止的字符串。
    嵌入式 SQL 数据类型
    设置长度的程序操作
    DT_BIGINT
    不需要任何操作
    DT_BINARY(n)
    采用 BINARY 结构中的字段的长度
    DT_BIT
    不需要任何操作
    DT_DATE
    由终止的 /0 决定的长度
    DT_DECIMAL(p,s)
    SQLDA 中长度字段的高字节设置为 p,低字节设置为 s
    DT_DOUBLE
    不需要任何操作
    DT_FIXCHAR(n)
    SQLDA 中的长度字段决定字符串的长度
    DT_FLOAT
    不需要任何操作
    DT_INT
    不需要任何操作
    DT_LONGBINARY
    忽略长度字段。请参见
    发送 LONG 数据

    DT_LONGVARCHAR
    忽略长度字段。请参见
    发送 LONG 数据

    DT_SMALLINT
    不需要任何操作
    DT_STRING
    由终止的 /0 决定的长度
    DT_TIME
    由终止的 /0 决定的长度
    DT_TIMESTAMP
    由终止的 /0 决定的长度
    DT_TIMESTAMP_STRUCT
    不需要任何操作
    DT_UNSBIGINT
    不需要任何操作
    DT_UNSINT
    不需要任何操作
    DT_UNSSMALLINT
    不需要任何操作
    DT_VARCHAR(n)
    采用 VARCHAR 结构中的字段的长度
    DT_VARIABLE
    由终止的 /0 决定的长度
    检索值
    下表指明在使用 SQLDA 从数据库中检索数据时长度字段的值。在检索数据时,从不修改 sqllen 字段。
    在这种情况下,只允许使用表中显示的接口数据类型。在从数据库检索信息时,使用 DT_DATE、DT_TIME 和 DT_TIMESTAMP 数据类型与使用 DT_STRING 的方式是相同的。值会被设置为当前日期格式的字符串。
    嵌入式 SQL 数据类型
    在接收时程序必须将长度字段设置为
    在读取值之后数据库返回长度信息的方式
    DT_BIGINT
    不需要任何操作
    不需要任何操作
    DT_BINARY(n)
    BINARY 结构的最大长度 (n+2)
    将 BINARY 结构的 len 字段设置为实际长度
    DT_BIT
    不需要任何操作
    不需要任何操作
    DT_DATE
    缓冲区的长度
    /0 位于字符串的末尾
    DT_DECIMAL(p,s)
    将高字节设置为 p 并将低字节设置为 s
    不需要任何操作
    DT_DOUBLE
    不需要任何操作
    不需要任何操作
    DT_FIXCHAR(n)
    缓冲区的长度
    通过填补空白至缓冲区的长度
    DT_FLOAT
    不需要任何操作
    不需要任何操作
    DT_INT
    不需要任何操作
    不需要任何操作
    DT_LONGBINARY
    忽略长度字段。请参见
    检索 LONG 数据

    忽略长度字段。请参见
    检索 LONG 数据

    DT_LONGVARCHAR
    忽略长度字段。请参见
    检索 LONG 数据

    忽略长度字段。请参见
    检索 LONG 数据

    DT_SMALLINT
    不需要任何操作
    不需要任何操作
    DT_STRING
    缓冲区的长度
    /0 位于字符串的末尾
    DT_TIME
    缓冲区的长度
    /0 位于字符串的末尾
    DT_TIMESTAMP
    缓冲区的长度
    /0 位于字符串的末尾
    DT_TIMESTAMP_ STRUCT
    不需要任何操作
    不需要任何操作
    DT_UNSBIGINT
    不需要任何操作
    不需要任何操作
    DT_UNSINT
    不需要任何操作
    不需要任何操作
    DT_UNSSMALLINT
    不需要任何操作
    不需要任何操作
    DT_VARCHAR(n)
    VARCHAR 结构的最大长度 (n+2)
    将 VARCHAR 结构的 len 字段设置为实际长度
    发送和检索 Long 型值
    在嵌入式 SQL 应用程序中,发送和检索 LONG VARCHAR 值和 LONG BINARY 值的方法与发送和检索其它数据类型的值的方法不同。虽然可以使用标准 SQLDA 字段,但是它们包含的数据不得超过 32 KB,因为保存信息的字段(sqldata、sqllen 和 sqlind)是 16 位值。将这些值更改为 32 位值会破坏现有的应用程序。
    说明 LONG VARCHAR 值和 LONG BINARY 值的方法与说明其它数据类型的方法相同。
    有关如何检索和发送值的信息,请参见
    检索 LONG 数据

    发送 LONG 数据

    静态 SQL 的用法
    使用单独的结构来保存 LONG BINARY 和 LONG VARCHAR 数据类型的已分配长度、已存储长度和未截断长度。静态 SQL 数据类型在 sqlca.h 中定义如下:
    #define DECL_LONGVARCHAR( size )         /
      struct { a_sql_uint32    array_len;    /
               a_sql_uint32    stored_len;   /
               a_sql_uint32    untrunc_len;  /
               char            array[size+1];/
             }
    #define DECL_LONGBINARY( size )          /
      struct { a_sql_uint32    array_len;    /
               a_sql_uint32    stored_len;   /
               a_sql_uint32    untrunc_len;  /
               char            array[size];  /
             }
    动态 SQL 的用法
    对于动态 SQL,根据需要将 sqltype 字段设置为 DT_LONGVARCHAR 或 DT_LONGBINARY。关联的 LONGBINARY 和 LONGVARCHAR 结构如下:
    typedef struct LONGVARCHAR {
        a_sql_uint32    array_len;
               /* number of allocated bytes in array */
        a_sql_uint32    stored_len;
               /* number of bytes stored in array
                * (never larger than array_len)
                */
        a_sql_uint32    untrunc_len;
               /* number of bytes in untruncated expression
                * (may be larger than array_len)
                */
        char            array[1];   /* the data */
    } LONGVARCHAR, LONGBINARY;
    有关如何在您的应用程序中实现此功能的信息,请参见
    检索 LONG 数据

    发送 LONG 数据

    检索 LONG 数据
    本节说明如何从数据库检索 LONG 值。有关背景信息,请参见
    发送和检索 Long 型值

    使用静态 SQL 时与使用动态 SQL 时的检索过程不同。
    接收 LONG VARCHAR 或 LONG BINARY 值(静态 SQL):

  • 根据需要声明类型为 DECL_LONGVARCHAR 或 DECL_LONGBINARY 的主机变量。

  • 使用 FETCH、GET DATA 或 EXECUTE INTO 检索数据。Adaptive Server Anywhere 设置以下信息:


    • 指示符变量    指示符变量在值为 NULL 时为负,在未发生截断时为 0,在发生截断时为未截断值的字节数(不超过 32767 的正数)。
      有关详细信息,请参见
      指示符变量

    • stored_len    此 DECL_LONGVARCHAR 或 DECL_LONGBINARY 字段保存检索到数组中的字节数。它绝不会大于 array_len

    • untrunc_len    此 DECL_LONGVARCHAR 或 DECL_LONGBINARY 字段保存数据库服务器所保存的字节数。它至少等于 stored_len 值。即使不截断值也会设置它。

    将值接收到 LONGVARCHAR 或 LONGBINARY 结构中(动态 SQL):

  • 根据需要将 sqltype 字段设置为 DT_LONGVARCHAR 或 DT_LONGBINARY。

  • sqldata 字段设置为指向 LONGVARCHAR 或 LONGBINARY 结构。
    您可以使用 LONGVARCHARSIZE( n ) 宏或 LONGBINARYSIZE( n ) 宏来确定为保存数组字段中的 n 字节数据而分配的总字节数。

  • 将 LONGVARCHAR 或 LONGBINARY 结构的 array_len 字段设置为分配给数组字段的字节数。

  • 使用 FETCH、GET DATA 或 EXECUTE INTO 检索数据。Adaptive Server Anywhere 设置以下信息:


    • * sqlind    sqlda 字段在值为 NULL 时为负,在未发生截断时为 0,在发生截断时为未截断值的字节数(不超过 32767 的正数)。

    • stored_len    此 LONGVARCHAR 或 LONGBINARY 字段保存检索到数组中的字节数。它绝不会大于 array_len

    • untrunc_len    此 LONGVARCHAR 或 LONGBINARY 字段保存数据库服务器所保存的字节数。它至少等于 stored_len 值。即使不截断值也会设置它。

    下面的代码段阐释了使用动态嵌入式 SQL 来检索 LONG VARCHAR 数据的机制。它并不是为实际的应用程序而准备的:
    #define DATA_LEN 128000
    void get_test_var()
    /*****************/
    {
        LONGVARCHAR *longptr;
        SQLDA *sqlda;
        SQLVAR *sqlvar;
        sqlda = alloc_sqlda( 1 );
        longptr = (LONGVARCHAR *)malloc(
                     LONGVARCHARSIZE( DATA_LEN ) );
        if( sqlda == NULL || longptr == NULL ) {
            fatal_error( "Allocation failed" );
        }
        // init longptr for receiving data
        longptr->array_len = DATA_LEN;
        // init sqlda for receiving data
        // (sqllen is unused with DT_LONG types)
        sqlda->sqld = 1;   // using 1 sqlvar
        sqlvar = &sqlda->sqlvar[0];
        sqlvar->sqltype = DT_LONGVARCHAR;
        sqlvar->sqldata = longptr;
        printf( "fetching test_var/n" );
        EXEC SQL PREPARE select_stmt FROM 'SELECT test_var';
        EXEC SQL EXECUTE select_stmt INTO DESCRIPTOR sqlda;
        EXEC SQL DROP STATEMENT select_stmt;
        printf( "stored_len: %d, untrunc_len: %d,
           1st char: %c, last char: %c/n",
            longptr->stored_len,
            longptr->untrunc_len,
            longptr->array[0],
            longptr->array[DATA_LEN-1] );
        free_sqlda( sqlda );
        free( longptr );
    }
    发送 LONG 数据
    本节说明如何将 LONG 值从嵌入式 SQL 应用程序发送到数据库。有关背景信息,请参见
    发送和检索 Long 型值

    使用静态 SQL 时与使用动态 SQL 时的检索过程不同。
    发送 LONG VARCHAR 或 LONG BINARY 值(静态 SQL):

  • 根据需要声明类型为 DECL_LONGVARCHAR 或 DECL_LONGBINARY 的主机变量。

  • 如果您要发送 NULL,并且使用了指示符变量,请将指示符变量设置为负值。
    有关详细信息,请参见
    指示符变量

  • 将 DECL_LONGVARCHAR 或 DECL_LONGBINARY 结构的 stored_len 字段设置为数组字段中的数据字节数。

  • 通过打开游标或执行语句发送数据。
    下面的代码段说明使用静态嵌入式 SQL 发送 LONG VARCHAR 的机制。它并不是为实际的应用程序而准备的。
    #define DATA_LEN 12800
    EXEC SQL BEGIN DECLARE SECTION;
    // SQLPP initializes longdata.array_len
    DECL_LONGVARCHAR(128000) longdata;
    EXEC SQL END DECLARE SECTION;
    void set_test_var()
    /*****************/
    {
        // init longdata for sending data
        memset( longdata.array, 'a', DATA_LEN );
        longdata.stored_len = DATA_LEN;
        printf( "Setting test_var to %d a's/n", DATA_LEN );
        EXEC SQL SET test_var = :longdata;
    }
    使用 LONGVARCHAR 或 LONGBINARY 结构发送值(动态 SQL):

  • 根据需要将 sqltype 字段设置为 DT_LONGVARCHAR 或 DT_LONGBINARY。

  • 如果您要发送 NULL,请将 * sqlind 设置为负值。

  • sqldata 字段设置为指向 LONGVARCHAR 或 LONGBINARY 结构。
    您可以使用 LONGVARCHARSIZE( n ) 宏或 LONGBINARYSIZE( n ) 宏来确定为保存数组字段中的 n 字节数据而分配的总字节数。

  • 将 LONGVARCHAR 或 LONGBINARY 结构的 array_len 字段设置为分配给数组字段的字节数。

  • 将 LONGVARCHAR 或 LONGBINARY 结构的 stored_len 字段设置为数组字段中的数据字节数。它一定不能大于 array_len

  • 通过打开游标或执行语句发送数据。
    使用存储过程
    本节说明如何在嵌入式 SQL 中使用 SQL 过程。
    使用简单的存储过程
    您可以在嵌入式 SQL 中创建和调用存储过程。
    您可以像嵌入任何其它数据定义语句(如 CREATE TABLE)那样嵌入 CREATE PROCEDURE。您还可以嵌入 CALL 语句以执行存储过程。下面的代码段说明如何在嵌入式 SQL 中创建和执行存储过程:
    EXEC SQL CREATE PROCEDURE pettycash( IN amount
       DECIMAL(10,2) )
    BEGIN
       UPDATE account
       SET balance = balance - amount
       WHERE name = 'bank';
       UPDATE account
       SET balance = balance + amount
       WHERE name = 'pettycash expense';
    END;
    EXEC SQL CALL pettycash( 10.72 );
    如果您希望将主机变量值传递到存储过程,或检索输出变量,请准备并执行 CALL 语句。下面的代码段说明主机变量的用法。USING 和 INTO 子句都在 EXECUTE 语句中使用。
    EXEC SQL BEGIN DECLARE SECTION;
       double  hv_expense;
       double  hv_balance;
    EXEC SQL END DECLARE SECTION;
    // code here
    EXEC SQL CREATE PROCEDURE pettycash(
             IN expense    DECIMAL(10,2),
             OUT endbalance DECIMAL(10,2) )
       BEGIN
          UPDATE account
          SET balance = balance - expense
          WHERE name = 'bank';
          UPDATE account
          SET balance = balance + expense
          WHERE name = 'pettycash expense';
          SET endbalance = ( SELECT balance FROM account
                             WHERE name = 'bank' );
       END;
    EXEC SQL PREPARE S1 FROM 'CALL pettycash( ?, ? )';
    EXEC SQL EXECUTE S1 USING :hv_expense INTO :hv_balance;
    有关详细信息,请参见
    EXECUTE 语句 [ESQL]

    PREPARE 语句 [ESQL]

    具有结果集的存储过程
    数据库过程也可以包含 SELECT 语句。声明该过程的方法是这样的:使用 RESULT 子句来指定结果集中列的编号、名称和类型。结果集列与输出参数不同。对于具有结果集的过程,在游标声明中可以使用 CALL 语句代替 SELECT 语句:
    EXEC SQL BEGIN DECLARE SECTION;
       char   hv_name[100];
    EXEC SQL END DECLARE SECTION;
    EXEC SQL CREATE PROCEDURE female_employees()
       RESULT( name char(50) )
       BEGIN
          SELECT emp_fname || emp_lname FROM employee
          WHERE sex = 'f';
       END;
    EXEC SQL PREPARE S1 FROM 'CALL female_employees()';
    EXEC SQL DECLARE C1 CURSOR FOR S1;
    EXEC SQL OPEN C1;
    for(;;) {
       EXEC SQL FETCH C1 INTO :hv_name;
       if( SQLCODE != SQLE_NOERROR ) break;
       printf( "%s//n", hv_name );
    }
    EXEC SQL CLOSE C1;
    在本示例中,使用 OPEN 语句而不是 EXECUTE 语句调用该过程。OPEN 语句会使该过程在到达 SELECT 语句之前一直执行。此时,C1 是数据库过程内的 SELECT 语句的游标。您可以使用所有形式的 FETCH 命令(向后和向前滚动),直到完成它为止。CLOSE 语句可终止该过程的执行。
    如果在该过程中在 SELECT 语句之后还有一条语句,则不会执行该语句。为了执行 SELECT 之后的语句,应使用 RESUME 游标名命令。RESUME 命令可返回警告 SQLE_PROCEDURE_COMPLETE,或返回指示存在另一游标的 SQLE_NOERROR。下面的示例阐释了一个双选择过程:
    EXEC SQL CREATE PROCEDURE people()
    RESULT( name char(50) )
    BEGIN
       SELECT emp_fname || emp_lname
       FROM employee;
       SELECT fname || lname
       FROM customer;
    END;
    EXEC SQL PREPARE S1 FROM 'CALL people()';
    EXEC SQL DECLARE C1 CURSOR FOR S1;
    EXEC SQL OPEN C1;
    while( SQLCODE == SQLE_NOERROR ) {
       for(;;) {
          EXEC SQL FETCH C1 INTO :hv_name;
          if( SQLCODE != SQLE_NOERROR ) break;
          printf( "%s//n", hv_name );
       }
       EXEC SQL RESUME C1;
    }
    EXEC SQL CLOSE C1;
    CALL 语句的动态游标
    以上这些示例使用了静态游标。也可以将完全动态的游标用于 CALL 语句。
    有关动态游标的说明,请参见
    动态 SELECT 语句

    DESCRIBE 语句完全适用于过程调用。DESCRIBE OUTPUT 生成的 SQLDA 具有每个结果集列的说明。
    如果过程没有结果集,则 SQLDA 具有过程的每个 INOUT 或 OUT 参数的说明。DESCRIBE INPUT 语句生成的 SQLDA 具有过程的每个 IN 或 INOUT 参数的说明。
    DESCRIBE ALL
    DESCRIBE ALL 说明 IN、INOUT、OUT 和 RESULT 等集合参数。DESCRIBE ALL 使用 SQLDA 中的指示符变量提供其它信息。
    当说明 CALL 语句时,会在指示符变量中设置 DT_PROCEDURE_IN 和 DT_PROCEDURE_OUT 位。DT_PROCEDURE_IN 指示 IN 或 INOUT 参数,而 DT_PROCEDURE_OUT 则指示 INOUT 或 OUT 参数。过程的 RESULT 列则清除这两个位。
    在说明 OUTPUT 之后,可以使用这些位来区分具有结果集的语句(需要使用 OPEN、FETCH、RESUME 和 CLOSE)和不具有结果集的语句(需要使用 EXECUTE)。
    有关完整说明,请参见
    DESCRIBE 语句 [ESQL]

    多个结果集
    如果具有一个返回多个结果集的过程,则在结果集改变形状时必须在每条 RESUME 语句之后重新说明。
    您需要说明游标(而不是语句),以重新说明游标的当前位置。
    嵌入式 SQL 编程技巧
    本节包含了一组可供嵌入式 SQL 程序开发人员使用的技巧。
    实现请求管理
    接口 DLL 的缺省行为是让应用程序在执行其它函数之前等待每个数据库请求的完成。可以使用请求管理函数更改这一行为。例如,在使用 Interactive SQL 时,操作系统在 Interactive SQL 等待数据库响应时仍处于活动状态,这时 Interactive SQL 可以执行一些别的任务。
    通过提供回调函数,您可以在数据库请求正在进行时完成应用程序的活动。在此回调函数中,您不能发出除 db_cancel_request 外的其它数据库请求。您可以在消息处理程序中使用 db_is_working 函数来确定是否有正在进行的数据库请求。
    db_register_a_callback 函数用于注册您的应用程序回调函数。
    有关详细信息,请参见以下内容:

    备份函数
    db_backup 函数在嵌入式 SQL 应用程序中提供对联机备份的支持。备份实用程序就利用了此函数。只有在 Adaptive Server Anywhere 备份实用程序无法满足您的备份要求时,才需要编写程序来使用此函数。
    建议使用 BACKUP 语句 虽然此函数提供了一种给应用程序添加备份功能的方法,但是建议您使用 BACKUP 语句来完成此任务。有关详细信息,请参见
    BACKUP 语句

    您也可以使用数据库工具 DBBackup 函数直接访问备份实用程序。有关此函数的详细信息,请参见
    DBBackup 函数

    有关详细信息,请参见
    db_backup 函数

    SQL 预处理器
    SQL 预处理器会在运行编译器之前处理包含嵌入式 SQL 的 C 或 C++ 程序。
    语法
    sqlpp [  options ] input-file [  output-file ]
    选项
    说明
    –c "keyword=value;..."
    提供参考数据库连接参数 [UltraLite]
    –d
    理想数据大小
    –e level
    将不符合要求的 SQL 语法标记为错误
    –f
    将 far 关键字置于生成的静态数据上
    –g
    不显示 UltraLite 警告
    –h linewidth
    限制输出的最大行长度
    –k
    包括 SQLCODE 的用户声明
    –m version
    为生成的同步脚本指定版本名称
    –n
    行号
    –o operatingsys
    目标操作系统。
    –p project
    UltraLite 项目名称
    –q
    安静模式:不打印横幅
    –r
    生成再入式代码
    –s stringlen
    编译器的最大字符串长度
    –w level
    将不符合要求的 SQL 语法标记为警告
    –x
    将多字节 SQL 字符串更改为转义序列
    –z sequence
    指定归类序列
    另请参见
    简介
    说明
    SQL 预处理器会在编译器运行之前处理包含嵌入式 SQL 的 C 或 C++ 程序。SQLPP 将 input-file 中的 SQL 语句转换为 C 语言源代码并将源代码放入 output-file。含有嵌入式 SQL 的源程序的扩展名通常为 .sqc。缺省的输出文件名是 input-file,其扩展名为 .c。如果 input-file 具有 .c 扩展名,则缺省的输出文件扩展名是 .cc
    选项
    –c    在对那些作为 UltraLite 应用程序组成部分的文件进行预处理时,此选项是必需的。连接字符串必须使 SQL 预处理器能够读取和修改您的参考数据库。
    –d    生成减小数据空间大小的代码。数据结构在使用之前执行时会得到重用和初始化。这会增大代码的大小。
    –e    如果嵌入式 SQL 不是 SQL/92 的指定集合的组成部分,此选项就会将其标记为错误。
    可用的 level 值及其含义如下:


    • e    标记不是入门级 SQL/92 语法的语法

    • i    标记不是中级 SQL/92 语法的语法

    • f    标记不是完整 SQL/92 语法的语法

    • t    标记非标准主机变量类型

    • u    标记 UltraLite 不支持的语法

    • w    允许所有支持的语法

    –g    不显示特定于 UltraLite 代码生成的警告。
    –h    将 sqlpp 输出的最大行长度限制为 num。行继续符是反斜杠 (/),num 的最小值是十。
    –k    通知预处理器,要编译的程序包括 SQLCODE 的用户声明。
    –m    为生成的同步脚本指定版本名称。可以在 MobiLink 统一数据库中使用生成的同步脚本进行简单同步。
    –n    在 C 文件中生成行号信息。该信息包括生成的 C 代码中适当位置处的 #line 指令。如果您使用的编译器支持 #line 指令,使用此选项可使编译器按照 SQC 文件(其中带有嵌入式 SQL)的行号报错,而不是用 SQL 预处理器生成的 C 文件的行号报错。此外,#line 指令由源代码级调试程序间接使用,以便您可以在查看 SQC 源文件时进行调试。
    –o    指定目标操作系统。注意,此选项必须与程序运行所使用的操作系统相匹配。在您的程序中会生成对特殊符号的引用。此符号在接口库中定义。如果您使用的操作系统说明或库是错误的,则链接程序会检测到一个错误。支持的操作系统有:


    • WINDOWS    Windows 95/98/Me、Windows CE

    • WINNT    Microsoft Windows NT/2000/XP

    • NETWARE    Novell NetWare

    • UNIX    UNIX

    –p    标识嵌入式 SQL 文件所属的 UltraLite 项目。仅当处理是 UltraLite 应用程序一部分的文件时才应用它。
    –q    不打印横幅。
    –r    有关再入式代码的详细信息,请参见
    多线程代码或再入式代码的 SQLCA 管理

    –s    设置预处理器放入 C 文件的最大大小的字符串。会使用一组字符('a''b''c' 等)对长度大于此值的字符串进行初始化。大多数 C 编译器都对可以处理的字符串大小有限制。此选项用于设置其上限。缺省值是 500。
    –w    如果嵌入式 SQL不是 SQL/92 的指定集合的组成部分,此选项就会将其标记为警告。
    可用的 level 值及其含义如下:


    • e    标记不是入门级 SQL/92 语法的语法

    • i    标记不是中级 SQL/92 语法的语法

    • f    标记不是完整 SQL/92 语法的语法

    • t    标记非标准主机变量类型

    • u    标记 UltraLite 不支持的语法

    • w    允许所有支持的语法

    –x    将多字节字符串更改为转义序列,以便它们可以通过编译器。
    –z    此选项指定归类序列。要查看建议使用的归类序列的列表,请在命令提示符下键入 dbinit –l
    归类序列用于帮助预处理器理解在程序源代码中使用的字符,例如,识别出适合在标识符中使用的字母字符。如果没有指定 -z,则预处理器会尝试根据操作系统和 SQLLOCALE 环境变量确定要使用的合理归类。
    库函数参考
    SQL 预处理器生成对接口库或 DLL 中的函数的调用。除了 SQL 预处理器生成的调用外,还提供了一组库函数方便数据库操作。EXEC SQL INCLUDE SQLCA 命令会包括这些函数的原型。
    本节包含这些不同函数的参考说明。
    DLL 入口点
    除了原型具有适合于 DLL 的修改程序外,DLL 入口点都是相同的。
    您可以使用在 sqlca.h 中定义的 _esqlentry_ 以可移植方式声明入口点。它解析为值 __stdcall:
    alloc_sqlda 函数
    alloc_sqlda_noind 函数
    db_backup 函数
    db_cancel_request 函数
    db_delete_file 函数
    db_find_engine 函数
    db_fini 函数
    db_get_property 函数
    db_init 函数
    db_is_working 函数
    db_locate_servers 函数
    db_locate_servers_ex 函数
    db_register_a_callback 函数
    db_start_database 函数
    db_start_engine 函数
    db_stop_database 函数
    db_stop_engine 函数
    db_string_connect 函数
    db_string_disconnect 函数
    db_string_ping_server 函数
    fill_s_sqlda 函数
    fill_sqlda 函数
    free_filled_sqlda 函数
    free_sqlda 函数
    free_sqlda_noind 函数
    sql_needs_quotes 函数
    sqlda_storage 函数
    sqlda_string_length 函数
    sqlerror_message 函数
    alloc_sqlda 函数
    原型
    SQLDA *alloc_sqlda( unsigned numvar );
    说明
    numvar 个变量的描述符分配给一个 SQLDA。将该 SQLDA 的 sqln 字段初始化为 numvar。为指示符变量分配空间,将指示符变量设置为指向此空间,并将指示符值初始化为零。如果无法分配内存,则返回空指针。建议您使用此函数代替 alloc_sqlda_noind 函数
    alloc_sqlda_noind 函数
    原型
    SQLDA *alloc_sqlda_noind( unsigned numvar );
    说明
    numvar 个变量的描述符分配给一个 SQLDA。将该 SQLDA 的 sqln 字段初始化为 numvar。不为指示符变量分配空间;将指示符指针设置为空指针。如果无法分配内存,则返回空指针。
    db_backup 函数
    原型
    void db_backup(
    SQLCA * sqlca,
    int op,
    int file_num,
    unsigned long page_num,
    SQLDA * sqlda );
    授权
    必须连接到具有 DBA 权限或 REMOTE DBA 权限 (SQL Remote) 的用户 ID。
    说明
    建议使用 BACKUP 语句 虽然此函数提供了一种给应用程序添加备份功能的方法,但是建议您使用 BACKUP 语句来完成此任务。有关详细信息,请参见
    BACKUP 语句

    执行的操作取决于 op 参数的值:


    • DB_BACKUP_START    必须先调用此函数,然后才能开始备份。对于任何给定的数据库服务器,一次只能运行一个备份。在备份完成之前禁用数据库检查点(使用 op 值 DB_BACKUP_END 调用 db_backup)。如果备份无法启动,则 SQLCODE 为 SQLE_BACKUP_NOT_STARTED。否则,将 sqlca 的 SQLCOUNT 字段设置为每个数据库页的大小。(一次一页地对备份进行处理。)
      忽略 file_numpage_numsqlda 参数。

    • DB_BACKUP_OPEN_FILE    打开由 file_num 指定的数据库文件,这允许使用 DB_BACKUP_READ_PAGE 备份指定文件的页。根数据库文件、事务日志文件和数据库写文件(如果存在)的有效文件编号分别为:0 到 DB_BACKUP_MAX_FILE、0 到 DB_BACKUP_TRANS_LOG_FILE 和 0 到 DB_BACKUP_WRITE_FILE。如果指定的文件不存在,则 SQLCODE 为 SQLE_NOTFOUND。否则,SQLCOUNT 包含文件中的页数,SQLIOESTIMATE 包含一个标识数据库文件创建时间的 32 位值 (POSIX time_t),SQLCA 的 sqlerrmc 字段包含操作系统文件名。
      忽略 page_numsqlda 参数。

    • DB_BACKUP_READ_PAGE    读取由 file_num 指定的数据库文件的一页。使用 DB_BACKUP_OPEN_FILE 操作对 db_backup 调用成功后会在 SQLCOUNT 中返回一个页数,page_num 值应介于 0 到此页数减去一得到的数之间。否则,SQLCODE 将设置为 SQLE_NOTFOUND。sqlda 描述符应使用一个指向缓冲区的 DT_BINARY 类型的变量建立。使用 DB_BACKUP_START 操作调用 db_backup 时会在 SQLCOUNT 字段中返回一个大小值,该缓冲区应足以保存此数量的二进制数据。
      DT_BINARY 数据包含一个后跟实际二进制数据的两字节长度值,因此缓冲区必须比页大小大两个字节。
      应用程序必须保存缓冲区 此调用会在缓冲区中制作指定数据库页的一个副本,但应由应用程序将缓冲区保存到某种备份介质。

    • DB_BACKUP_READ_RENAME_LOG    此操作与 DB_BACKUP_READ_PAGE 只有一点不同:事务日志的最后一页返回之后,数据库服务器会重命名事务日志并启动一个新的事务日志。
      如果数据库服务器无法在当前时间重命名日志(例如,在 7.x 版或更早版本的数据库中可能存在未完成的事务),则会设置 SQLE_BACKUP_CANNOT_RENAME_LOG_YET 错误。在这种情况下,不要使用返回的页,而是要重新发出请求,直到收到 SQLE_NOERROR,然后写入页。继续阅读页,直到收到 SQLE_NOTFOUND 条件。
      可能会在多个页上多次返回 SQLE_BACKUP_CANNOT_RENAME_LOG_YET 错误。您应该在重试循环中增加延迟,以便不会因请求过多而降低服务器的速度。
      当您收到 SQLE_NOTFOUND 条件时,事务日志已经成功备份且文件已经重命名。旧日志文件的名称在 SQLCA 的 sqlerrmc 字段中返回。
      您应在 db_backup 调用后检查 sqlda->sqlvar[0].sqlind 值。如果此值大于零,则最后一个日志页已经写入且日志文件已经重命名。新名称仍然在 sqlca.sqlerrmc 中,但 SQLCODE 值是 SQLE_NOERROR。
      此后,您不应再次调用 db_backup(除非要关闭文件并完成备份),否则,您会获得备份日志文件的第二份副本并收到 SQLE_NOTFOUND。

    • DB_BACKUP_CLOSE_FILE    处理完一个文件后必须调用此函数以关闭由 file_num 指定的数据库文件。
      忽略 page_numsqlda 参数。

    • DB_BACKUP_END    备份结束时必须调用此函数。在此备份结束之前,任何其它备份都无法启动。会再次启用检查点。
      忽略 file_numpage_numsqlda 参数。

    dbbackup 程序使用下面的算法。注意,这不是 C 代码,不包括错误检查。
    db_backup( ... DB_BACKUP_START ... )
    allocate page buffer based on page size in SQLCODE
    sqlda = alloc_sqlda( 1 )
    sqlda->sqld = 1;
    sqlda->sqlvar[0].sqltype = DT_BINARY
    sqlda->sqlvar[0].sqldata = allocated buffer
    for file_num = 0 to DB_BACKUP_MAX_FILE
      db_backup( ... DB_BACKUP_OPEN_FILE, file_num ... )
      if SQLCODE == SQLE_NO_ERROR
        /* The file exists */
        num_pages = SQLCOUNT
        file_time = SQLE_IO_ESTIMATE
        open backup file with name from sqlca.sqlerrmc
        for page_num = 0 to num_pages - 1
          db_backup( ... DB_BACKUP_READ_PAGE,
                    file_num, page_num, sqlda )
          write page buffer out to backup file
        next page_num
        close backup file
        db_backup( ... DB_BACKUP_CLOSE_FILE, file_num ... )
      end if
    next file_num
    backup up file DB_BACKUP_WRITE_FILE as above
    backup up file DB_BACKUP_TRANS_LOG_FILE as above
    free page buffer
    db_backup( ... DB_BACKUP_END ... )
    db_cancel_request 函数
    原型
    int db_cancel_request( SQLCA *sqlca );
    说明
    取消当前活动的数据库服务器请求。此函数会进行检查,以确保在发送取消请求之前数据库服务器请求是活动的。如果此函数返回 1,则发送取消请求;如果它返回 0,则不发送请求。
    一个非零返回值不表示请求被取消。在几个临界时刻,取消请求和来自数据库或服务器的响应会 [交错]。在这些情况下,即使函数仍然返回 TRUE,取消请求也没有效果。
    可以异步调用 db_cancel_request 函数。数据库接口库中只有此函数和 db_is_working 可以使用 SQLCA(可能正被另一请求使用)进行异步调用。
    如果您取消正在执行游标操作的请求,则游标的位置是不确定的。在取消之后,您必须按游标的绝对位置定位该游标或关闭它。
    db_delete_file 函数
    原型
    void db_delete_file(
    SQLCA * sqlca,
    char * filename );
    授权
    必须连接到具有 DBA 权限或 REMOTE DBA 权限 (SQL Remote) 的用户 ID。
    说明
    db_delete_file 函数请求数据库服务器删除 filename。可以在备份和重命名事务日志(请参见
    db_backup 函数
    中的 DB_BACKUP_READ_RENAME_LOG)之后使用它来删除旧事务日志。您必须连接到具有 DBA 权限的用户 ID。
    db_find_engine 函数
    原型
    unsigned short db_find_engine(
    SQLCA *sqlca,
    char *name );
    说明
    返回无符号的短值,该值指示有关名为 name 的数据库服务器的状态信息。如果找不到具有指定名称的服务器,则返回值为 0。非零值指示服务器当前正在运行。
    返回值中的每个位都指示某一信息。代表不同信息段的位的常量在 sqldef.h 头文件中定义。如果为 name 指定了空指针,则返回有关缺省数据库环境的信息。
    db_fini 函数
    原型
    unsigned short db_fini( SQLCA *sqlca );
    说明
    此函数释放由数据库接口或 DLL 使用的资源。在调用 db_fini 之后不能进行任何其它库调用或执行任何嵌入式 SQL 命令。如果在处理过程中出现错误,则在 SQLCA 中设置错误代码且函数返回 0。如果没有错误,则返回非零值。
    需要为每个使用的 SQLCA 调用一次 db_fini
    注意    对于 NetWare 上的每个 db_init,如果未能调用 db_fini,则会导致数据库服务器和 NetWare 文件服务器出现故障。
    另请参见
    有关在 UltraLite 应用程序中使用 db_init 的信息,请参见
    db_fini 函数

    db_get_property 函数
    原型
    unsigned int db_get_property(
    SQLCA * sqlca,
    a_db_property property,
    char * value_buffer,
    int value_buffer_size );
    说明
    此函数用于获得您当前连接到的服务器的地址。dbping 实用程序使用它来显示输出服务器地址。
    也可以使用此函数获得数据库属性的值。如
    数据库属性
    中所述,也可以通过执行 SELECT 语句以独立于接口的方式获得数据库属性。
    参数如下:


    • a_db_property    具有值 DB_PROP_SERVER_ADDRESS 的 enum。DB_PROP_SERVER_ADDRESS 获取当前连接的服务器网络地址,作为可打印字符串。共享内存和 NamedPipes 协议始终会为地址返回空字符串。TCP/IP 和 SPX 协议会返回非空字符串地址。

    • value_buffer    此参数填充的是以空值终止的字符串形式的属性值。

    • value_buffer_size    字符串 value_buffer 的最大长度,其中包括终止的空字符。

    另请参见
    数据库属性
    db_init 函数
    原型
    unsigned short db_init( SQLCA *sqlca );
    说明
    此函数初始化数据库接口库。在进行任何其它库调用之前和执行任何嵌入式 SQL 命令之前,都必须调用此函数。在进行此调用时将分配和初始化接口库对您的程序所要求的资源。
    在程序结尾处使用 db_fini 来释放资源。如果在处理过程中出现错误,则在 SQLCA 中返回这些错误且返回 0。如果没有错误,则返回非零值,您就可以开始使用嵌入式 SQL 命令和函数。
    在大多数情况下,只应调用一次该函数(传递 sqlca.h 头文件中定义的全局 sqlca 变量的地址)。如果您要使用嵌入式 SQL 来编写具有多个线程的 DLL 或应用程序,则每使用一个 SQLCA,就要调用一次 db_init
    有关详细信息,请参见
    多线程代码或再入式代码的 SQLCA 管理

    注意    对于 NetWare 上的每个 db_init,如果未能调用 db_fini,则会导致数据库服务器和 NetWare 文件服务器出现故障。
    另请参见
    有关在 UltraLite 应用程序中使用 db_init 的信息,请参见
    db_init 函数

    db_is_working 函数
    原型
    unsigned db_is_working( SQLCA *sqlca );
    说明
    如果您的应用程序有一个使用了给定的 sqlca的数据库请求正在进行中,则返回 1;若没有这样的请求在进行中,则返回 0。
    可以异步调用此函数。数据库接口库中只有此函数和 db_cancel_request 可以使用 SQLCA(可能正被另一请求使用)进行异步调用。
    db_locate_servers 函数
    原型
    unsigned int db_locate_servers(
    SQLCA *sqlca,
    SQL_CALLBACK_PARM callback_address,
    void *callback_user_data );
    说明
    提供对 dblocate 实用程序所显示的信息的编程式访问,列出本地网络上正在监听 TCP/IP 的所有 Adaptive Server Anywhere 数据库服务器。
    回调函数必须具有以下原型:
    int (*)( SQLCA *sqlca,
    a_server_address *server_addr,
    void *callback_user_data );
    对于找到的每台服务器都要调用回调函数。如果回调函数返回 0,则 db_locate_servers 停止迭代通过服务器。
    传递到回调函数的 sqlcacallback_user_data 是那些传递到 db_locate_servers 中的函数。第二个参数是指向 a_server_address 结构的指针。a_server_address 是在 sqlca.h 中定义的,所使用的定义如下:
    typedef struct a_server_address {
        a_SQL_uint32   port_type;
        a_SQL_uint32   port_num;
        char       *name;
        char       *address;
    } a_server_address;


    • port_type    它在此时始终是 PORT_TYPE_TCP(在 sqlca.h 中定义为 6)。

    • port_num    它是此服务器正在监听的 TCP 端口号。

    • name    指向包含服务器名称的缓冲区。

    • address    指向包含服务器 IP 地址的缓冲区。

    有关详细信息,请参见
    服务器定位实用程序

    db_locate_servers_ex 函数
    原型
    unsigned int db_locate_servers_ex(
    SQLCA *sqlca,
    SQL_CALLBACK_PARM callback_address,,
    void *callback_user_data
    unsigned int bitmask);
    说明
    提供对 dblocate 实用程序所显示的信息的编程式访问,列出本地网络上正在监听 TCP/IP 的所有 Adaptive Server Anywhere 数据库服务器,并提供用于选择传递给回调例程的地址的掩码参数。
    回调函数必须具有以下原型:
    int (*)( SQLCA *sqlca,
    a_server_address *server_addr,
    void *callback_user_data );
    对于每台满足位掩码的服务器,回调函数都被调用。如果回调函数返回 0,则 db_locate_servers_ex 停止迭代通过服务器。
    传递到回调函数的 sqlcacallback_user_data 是那些传递到 db_locate_servers 中的函数。第二个参数是指向 a_server_address 结构的指针。a_server_address 是在 sqlca.h 中定义的,所使用的定义如下:
    typedef struct a_server_address {
        a_SQL_uint32   port_type;
        a_SQL_uint32   port_num;
        char       *name;
        char       *address;
    } a_server_address;


    • port_type    它在此时始终是 PORT_TYPE_TCP(在 sqlca.h 中定义为 6)。

    • port_num    它是此服务器正在监听的 TCP 端口号。

    • name    指向包含服务器名称的缓冲区。

    • address    指向包含服务器 IP 地址的缓冲区。

    当前仅支持一个位掩码标记 DB_LOOKUP_FLAG_NUMERIC。此标记在 sqlca.h 中定义。它确保传递给回调例程的地址是 IP 地址,而不是主机名。
    有关详细信息,请参见
    服务器定位实用程序

    db_register_a_callback 函数
    原型
    void db_register_a_callback(
    SQLCA *sqlca,
    a_db_callback_index index,
    ( SQL_CALLBACK_PARM ) callback );
    说明
    此函数注册回调函数。
    如果您不注册 DB_CALLBACK_WAIT 回调,则缺省操作是不执行任何操作。您的应用程序会被阻塞,等待数据库响应,并且 Windows 会将光标更改为沙漏光标。
    要删除回调,请传递一个空指针作为 callback 函数。
    对于 index 参数,允许使用以下值:


    • DB_CALLBACK_DEBUG_MESSAGE    对每条调试信息都要调用一次提供的函数,而且会有一个包含该调试信息文本的以空值终止的字符串传递给该函数。该字符串通常在紧邻终止的空字符之前有一个换行符 (/n)。回调函数的原型如下:
      void SQL_CALLBACK debug_message_callback(
      SQLCA *sqlca,
      char * message_string );

    • DB_CALLBACK_START    原型如下:
      void SQL_CALLBACK start_callback( SQLCA *sqlca );
      此函数是在数据库请求发送到服务器之前被调用的。DB_CALLBACK_START 只用于 Windows。

    • DB_CALLBACK_FINISH    原型如下:
      void SQL_CALLBACK finish_callback( SQLCA * sqlca );
      在接口 DLL 已接收到对数据库请求的响应之后,调用此函数。DB_CALLBACK_FINISH 仅在 Windows 操作系统上使用。

    • DB_CALLBACK_CONN_DROPPED    原型如下:
      void SQL_CALLBACK conn_dropped_callback (
      SQLCA *sqlca,
      char *conn_name );
      当数据库服务器要通过 DROP CONNECTION 语句删除连接(因活动超时或因该数据库服务器在关闭)时,调用此函数。连接名称 conn_name 会传递给此函数,以便使您能够区分连接。如果没有命名连接,则它具有 NULL 值。

    • DB_CALLBACK_WAIT    原型如下:
      void SQL_CALLBACK wait_callback( SQLCA *sqlca );
      在数据库服务器或客户端库忙于处理您的数据库请求的同时,接口库反复调用此函数。
      您可以按如下所示注册此回调函数:
      db_register_a_callback( &sqlca,
         DBCALLBACK_WAIT,
         (SQL_CALLBACK_PARM)&db_wait_request );

    • DB_CALLBACK_MESSAGE    使用此函数后,应用程序可以对处理请求期间从服务器接收的消息进行处理。
      回调原型如下:
      void SQL_CALLBACK message_callback(
      SQLCA* sqlca,
      unsigned char msg_type,
      an_SQL_code code,
      unsigned short length,
      char*  msg
      );
      msg_type 参数说明了消息的重要性,而您可能需要以不同方式处理不同的消息。可供使用的消息类型有 MESSAGE_TYPE_INFO、MESSAGE_TYPE_WARNING、MESSAGE_TYPE_ACTION 和 MESSAGE_TYPE_STATUS。这些常量是在 sqldef.h 中定义的。code 字段是标识符。length 字段指定消息的长度。消息是以空值终止的。
      例如,Interactive SQL 回调在 [消息] 窗格中显示 STATUS 和 INFO 消息,而在对话框中显示类型为 ACTION 和 WARNING 的消息。如果应用程序不注册此回调,会有一个缺省回调,它导致将所有消息写入服务器日志文件(如果正在调试并指定了日志文件)。另外,MESSAGE_TYPE_WARNING 和 MESSAGE_TYPE_ACTION 等类型的消息会以与操作系统相关的方式更为突出地显示。

    db_start_database 函数
    原型
    unsigned int db_start_database( SQLCA * sqlca, char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    如果数据库没有在运行中。在现有服务器上启动数据库(如果可能)。否则,启动新的服务器。
    查找服务器
    中说明了启动数据库的步骤。
    如果数据库已运行或已成功启动,则返回值为真(非零)并且将 SQLCODE 设置为 0。错误消息在 SQLCA 中返回。
    如果在参数中提供了用户 ID 和口令,则它们将被忽略。
    启动和停止数据库所需的权限在服务器命令行上设置。有关信息,请参见
    数据库服务器

    db_start_engine 函数
    原型
    unsigned int db_start_engine( SQLCA * sqlca, char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    如果数据库服务器没有运行且提供了 DBF 参数,则启动数据库服务器。
    查找服务器
    中列出了此函数执行的步骤。
    如果数据库已运行或已成功启动,则返回值为真(非零)并且将 SQLCODE 设置为 0。错误消息在 SQLCA 中返回。
    下面对 db_start_engine 的调用会启动数据库服务器并将其命名为 asademo,虽然使用了 DBF 连接参数,但不会装载数据库:
    db_start_engine( &sqlca,
        "DBF=c://asa9//asademo.db; Start=dbeng9" );
    如果您希望既启动服务器也启动数据库,请在 START 连接参数中包括数据库文件:
    db_start_engine( &sqlca,
       "ENG=eng_name;START=dbeng9 c://asa//asademo.db" );
    此调用启动服务器,将其命名为 eng_name,并启动该服务器上的 asademo 数据库。
    db_start_engine 函数在尝试启动某个服务器之前会先尝试连接到它,以免出现试图启动已在运行的服务器的情况。
    FORCESTART 连接参数仅由 db_start_engine 函数使用。当设置为 YES 时,在尝试启动服务器之前不尝试连接到服务器。这样,下面的一对命令就能够按预期方式工作:

  • 启动名为 server_1 的数据库服务器:
    start dbeng9 -n server_1 asademo.db

  • 强制启动一台新服务器并连接到它:
    db_start_engine( &sqlda,
      "START=dbeng9 -n server_2 asademo.db;ForceStart=YES" )
    如果没有使用 FORCESTART,且没有 ENG 参数,则第二个命令会尝试连接到 server_1。db_start_engine 函数不从 START 参数的 -n 选项获取服务器名。
    db_stop_database 函数
    原型
    unsigned int db_stop_database( SQLCA * sqlca, char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    在由 EngineName 标识的服务器上停止由 DatabaseName 标识的数据库。如果未指定 EngineName,则使用缺省的服务器。
    缺省情况下,此函数不停止有现有连接的数据库。如果 Unconditionalyes,则不管是否有现有连接都会停止数据库。
    返回值 TRUE 指示没有错误。
    启动和停止数据库所需的权限在服务器命令行上设置。有关信息,请参见
    数据库服务器

    db_stop_engine 函数
    原型
    unsigned int db_stop_engine( SQLCA * sqlca, char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    终止数据库服务器的执行。此函数执行的步骤有:


    • 查找具有与 EngineName 参数匹配的名称的本地数据库服务器。如果未指定 EngineName,则查找缺省的本地数据库服务器。

    • 如果找不到匹配的服务器,则此函数失败。

    • 向服务器发送一个请求,让服务器执行检查点操作并关闭所有数据库。

    • 卸载数据库服务器。

    缺省情况下,此函数不停止有现有连接的数据库。如果 Unconditionalyes,则不管是否有现有连接都会停止数据库服务器。
    C 程序可以使用此函数,而不用衍生 DBSTOP。返回值 TRUE 指示没有错误。
    是否可以使用 db_stop_engine 取决于在 -gk 服务器选项上设置的权限。
    有关详细信息,请参见
    -gk 服务器选项

    db_string_connect 函数
    原型
    unsigned int db_string_connect( SQLCA * sqlca, char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    提供了 SQL CONNECT 命令所具有的功能以外的其它功能。此函数使用在
    疑难解答连接
    中说明的算法执行连接。
    如果成功建立连接则返回值为真(非零),否则返回值为假(零)。有关启动服务器、启动数据库或进行连接的错误消息均在 SQLCA 中返回。
    db_string_disconnect 函数
    原型
    unsigned int db_string_disconnect(
        SQLCA * sqlca,
        char * parms );
    参数
    sqlca    指向 SQLCA 结构的指针。有关信息,请参见
    SQL 通信区域 (SQLCA)

    parms    以 NULL 终止的字符串,其中包含以分号分隔的参数设置列表,每个参数设置的形式均为 KEYWORD=value。例如,"UID=DBA;PWD=SQL;DBF=c://db//mydatabase.db"
    有关可用连接参数的列表,请参见
    连接参数

    说明
    此函数断开由 ConnectionName 参数标识的连接。忽略所有其它参数。
    如果在字符串中未指定 ConnectionName 参数,则断开未命名的连接。它等效于嵌入式 SQL DISCONNECT 命令。如果连接成功结束,则布尔返回值为真。错误消息在 SQLCA 中返回。
    如果数据库是使用 AutoStop=yes 参数启动的且没有其它到该数据库的连接,则此函数关闭该数据库。如果服务器是使用 AutoStop=yes 参数启动的且没有其它正在运行的数据库,它也会停止该服务器。
    db_string_ping_server 函数
    原型
    unsigned int db_string_ping_server(
    SQLCA * sqlca,
    char * connect_string,
    unsigned int   connect_to_db );
    说明
    connect_string 是一个常规连接字符串,它可能包含服务器和数据库信息,也可能不包含。
    如果 connect_to_db 为非零(真),此函数会尝试连接到服务器上的数据库。只有在连接字符串足以连接到指定服务器上的指定数据库时,才返回非零(真)值。
    如果 connect_to_db 为零,则此函数仅尝试定位服务器。只有在连接字符串足以定位服务器时,才返回非零值。它不尝试连接到数据库。
    fill_s_sqlda 函数
    原型
    struct sqlda * fill_s_sqlda(
    struct sqlda * sqlda,
    unsigned int maxlen );
    说明
    fill_sqlda 相同,只不过它将 sqlda 中的所有数据类型更改为类型 DT_STRING。将分配足够的空间,以保存最初由 SQLDA 指定的类型的字符串表示,最大为 maxlen 字节。会相应修改 SQLDA 中的长度字段 (sqllen)。如果成功则返回 sqlda;如果没有足够的可用内存则返回空指针。
    fill_sqlda 函数
    原型
    struct sqlda * fill_sqlda( struct sqlda * sqlda );
    说明
    为在 sqlda 的每个描述符中说明的每个变量分配空间,并将此内存的地址指派给对应描述符的 sqldata 字段。为描述符中指明的数据库类型和长度分配足够的空间。如果成功则返回 sqlda;如果没有足够的可用内存则返回空指针。
    free_filled_sqlda 函数
    原型
    void free_filled_sqlda( struct sqlda * sqlda );
    说明
    释放分配给每个 sqldata 指针的内存和分配给 SQLDA 自身的空间。不释放任何空指针。
    调用此函数会导致自动调用 free_sqlda,因此由 alloc_sqlda 分配的任何描述符都被释放。
    free_sqlda 函数
    原型
    void free_sqlda( struct sqlda * sqlda );
    说明
    释放分配给此 sqlda 的空间并释放指示符变量空间,这些空间是在 fill_sqlda 中分配的。不会释放每个 sqldata 指针引用的内存。
    free_sqlda_noind 函数
    原型
    void free_sqlda_noind( struct sqlda * sqlda );
    说明
    释放分配给此 sqlda 的空间。不会释放每个 sqldata 指针引用的内存。将忽略指示符变量指针。
    数据库属性
    Ping 实用程序
    sql_needs_quotes 函数
    原型
    unsigned int sql_needs_quotes( SQLCA *sqlca, char *str );
    说明
    返回一个布尔值,指示当字符串用作 SQL 标识符时是否需要用双引号括起来。此函数向数据库服务器发出请求以确定是否需要引号。相关信息存储在 sqlcode 字段中。
    返回值/代码的组合有三种情况:


    • return = FALSE, sqlcode = 0    在这种情况下,字符串肯定不需要引号。

    • return = TRUE    在这种情况下,sqlcode 始终是 SQLE_WARNING,字符串肯定需要引号。

    • return = FALSE    如果 sqlcode 不是 SQLE_WARNING,则此测试不能确定是否需要引号。

    sqlda_storage 函数
    原型
    unsigned long sqlda_storage( struct sqlda *sqlda, int varno );
    说明
    返回存储量,该存储量是存储 sqlda->sqlvar[varno] 中所说明的变量的任意值时所需的。
    sqlda_string_length 函数
    原型
    unsigned long sqlda_string_length( SQLDA *sqlda, int varno );
    说明
    返回保存变量 sqlda->sqlvar[varno](不管其类型是什么)所需的 C 字符串(类型为 DT_STRING)的长度。
    sqlerror_message 函数
    原型
    char *sqlerror_message( SQLCA *sqlca, char * buffer, int max );
    说明
    返回到包含错误消息的字符串的指针。错误消息包含 SQLCA. 中的错误代码的文本。如果没有指出错误,则返回空指针。将错误消息置于提供的缓冲区中,如有必要则将其截至长度 max
    嵌入式 SQL 命令汇总
    EXEC SQL  所有嵌入式 SQL 语句都必须以 EXEC SQL 开头且以分号 (;) 结尾。
    有两组嵌入式 SQL 命令。标准 SQL 命令的用法是:只需将其置于 C 程序中,并在其前后分别加上 EXEC SQL 和分号 (;) 即可。CONNECT、DELETE、SELECT、SET 和 UPDATE有一些附加格式只能在嵌入式 SQL 中使用。具有这些格式的命令属于特定于嵌入式 SQL 的命令的第二个类别。
    有关标准 SQL 命令的说明,请参见
    SQL 语句

    有几个 SQL 命令是特定于嵌入式 SQL 的并只能在 C 程序中使用。
    有关嵌入式 SQL 命令的详细信息,请参见
    SQL 语言元素

    可以从嵌入式 SQL 应用程序使用标准的数据操纵语句和数据定义语句。另外,下列语句也是专用于嵌入式 SQL 编程的语句:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值