504
Adaptive Server Anywhere 编程指南 编程指南 编程指南 编程指南 部件号:32068-01-0802-01 上次修改时间:2002 10

Adaptive Server Anywhere

  • Upload
    others

  • View
    9

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Adaptive Server Anywhere

Adaptive Server Anywhere编程指南编程指南编程指南编程指南

部件号: 32068-01-0802-01

上次修改时间: 2002 年 10 月

Page 2: Adaptive Server Anywhere

版权所有 © 1989-2003 Sybase, Inc. Portions 版权所有 © 2001-2003 iAnywhere Solutions, Inc. 保留所有权利。

未经 Sybase, Inc. 事先书面许可,不得以任何形式、任何手段 (电子的、机械的、手工的、光学的或其它方式)复制、传播或翻译本书的任何部分。

Sybase、 SYBASE(徽标)、 AccelaTrade、 ADA Workbench、 Adaptable Windowing Environment、 Adaptive Component Architecture、 Adaptive Server、 Adaptive Server Anywhere、 Adaptive Server Enterprise、 Adaptive Server Enterprise Monitor、 Adaptive Server Enterprise Replication、 Adaptive Server Everywhere、 Adaptive Server IQ、 Adaptive Warehouse、AnswerBase、 Anywhere Studio、 Application Manager、 AppModeler、 APT Workbench、 APT-Build、 APT-Edit、APT-Execute、 APT-FORMS、 APT-Library、 APT-Translator、 ASEP、 Backup Server、 BayCam、 Bit-Wise、BizTracker、 Certified PowerBuilder Developer、 Certified SYBASE Professional、 Certified SYBASE Professional(徽标)、ClearConnect、 Client Services、 Client-Library、 CodeBank、 Column Design、 ComponentPack、 Connection Manager、Convoy/DM、 Copernicus、 CSP、 Data Pipeline、 Data Workbench、 DataArchitect、 Database Analyzer、 DataExpress、DataServer、 DataWindow、 DB-Library、 dbQueue、 Developers Workbench、 Direct Connect Anywhere、 DirectConnect、Distribution Director、 Dynamo、 e-ADK、 E-Anywhere、 e-Biz Integrator、 E-Whatever、 EC-GATEWAY、 ECMAP、ECRTP、 eFulfillment Accelerator、 Electronic Case Management、 Embedded SQL、 EMS、 Enterprise Application Studio、Enterprise Client/Server、 Enterprise Connect、 Enterprise Data Studio、 Enterprise Manager、 Enterprise SQL Server Manager、 Enterprise Work Architecture、 Enterprise Work Designer、 Enterprise Work Modeler、 eProcurement Accelerator、eremote、 Everything Works Better When Everything Works Together、 EWA、 Financial Fusion、 Financial Fusion Server、First Impression、 Formula One、 Gateway Manager、 GeoPoint、 iAnywhere、 iAnywhere Solutions、 ImpactNow、Industry Warehouse Studio、 InfoMaker、 Information Anywhere、 Information Everywhere、 InformationConnect、InstaHelp、 Intellidex、 InternetBuilder、 iremote、 iScript、 Jaguar CTS、 jConnect for JDBC、 KnowledgeBase、 Logical Memory Manager、 MainframeConnect、 Maintenance Express、 MAP、 MDI Access Server、 MDI Database Gateway、media.splash、 MetaWorks、 MethodSet、 ML Query、 MobiCATS、 MySupport、 Net-Gateway、 Net-Library、 New Era of Networks、 Next Generation Learning、 Next Generation Learning Studio、 O DEVICE、 OASiS、 OASiS(徽标)、ObjectConnect、 ObjectCycle、 OmniConnect、 OmniSQL Access Module、 OmniSQL Toolkit、 Open Biz、 Open Business Interchange、 Open Client、 Open Client/Server、 Open Client/Server Interfaces、 Open ClientConnect、 Open Gateway、Open Server、 Open ServerConnect、 Open Solutions、 Optima++、 Partnerships that Work、 PB-Gen、 PC APT Execute、PC DB-Net、 PC Net Library、 PhysicalArchitect、 Pocket PowerBuilder、 PocketBuilder、 Power Through Knowledge、Power++、 power.stop、 PowerAMC、 PowerBuilder、 PowerBuilder Foundation Class Library、 PowerDesigner、PowerDimensions、 PowerDynamo、 Powering the New Economy、 PowerJ、 PowerScript、 PowerSite、 PowerSocket、Powersoft、 Powersoft Portfolio、 Powersoft Professional、 PowerStage、 PowerStudio、 PowerTips、 PowerWare Desktop、PowerWare Enterprise、 ProcessAnalyst、 Rapport、 Relational Beans、 Replication Agent、 Replication Driver、 Replication Server、 Replication Server Manager、 Replication Toolkit、 Report Workbench、 Report-Execute、 Resource Manager、RW-DisplayLib、 RW-Library、 S Designor、 S-Designor、 S.W.I.F.T. Message Format Libraries、 SAFE、 SAFE/PRO、SDF、 Secure SQL Server、 Secure SQL Toolset、 Security Guardian、 SKILS、 smart.partners、 smart.parts、 smart.script、SQL Advantage、 SQL Anywhere、 SQL Anywhere Studio、 SQL Code Checker、 SQL Debug、 SQL Edit、 SQL Edit/TPU、 SQL Everywhere、 SQL Modeler、 SQL Remote、 SQL Server、 SQL Server Manager、 SQL Server SNMP SubAgent、 SQL Server/CFT、 SQL Server/DBM、 SQL SMART、 SQL Station、 SQL Toolset、 SQLJ、 Stage III Engineering、 Startup.Com、 STEP、 SupportNow、 Sybase Central、 Sybase Client/Server Interfaces、 Sybase Development Framework、 Sybase Financial Server、 Sybase Gateways、 Sybase Learning Connection、 Sybase MPP、 Sybase SQL Desktop、 Sybase SQL Lifecycle、 Sybase SQL Workgroup、 Sybase Synergy Program、 Sybase User Workbench、 Sybase Virtual Server Architecture、 SybaseWare、 Syber Financial、 SyberAssist、 SybMD、 SyBooks、 System 10、 System 11、System XI(徽标)、 SystemTools、 Tabular Data Stream、 The Enterprise Client/Server Company、 The Extensible Software Platform、 The Future Is Wide Open、 The Learning Connection、 The Model For Client/Server Solutions、 The Online Information Center、 The Power of One、 TradeForce、 Transact-SQL、 Translation Toolkit、 Turning Imagination Into Reality、 UltraLite、 UNIBOM、 Unilib、 Uninull、 Unisep、 Unistring、 URK Runtime Kit for UniCode、 Viewer、 Visual Components、 VisualSpeller、 VisualWriter、 VQL、 Warehouse Control Center、 Warehouse Studio、 Warehouse WORKS、WarehouseArchitect、 Watcom、 Watcom SQL、 Watcom SQL Server、 Web Deployment Kit、 Web.PB、 Web.SQL、WebSights、 WebViewer、 WorkGroup SQL Server、 XA-Library、 XA-Server 以及 XP Server 是 Sybase, Inc. 或其子公司的商标。

所有其它商标均归各自的所有者所有。

Page 3: Adaptive Server Anywhere

目录目录目录目录目录目录目录目录

关于本手册关于本手册关于本手册关于本手册 ................................................................................... vii

1 编程接口概述编程接口概述编程接口概述编程接口概述.................................................................................. 1ODBC 编程接口 ..................................................................................2OLE DB 编程接口................................................................................3" 嵌入式 SQL" 编程接口 ......................................................................4JDBC 编程接口....................................................................................5Open Client 编程接口 ...........................................................................6

2 在应用程序中使用在应用程序中使用在应用程序中使用在应用程序中使用 SQL...........................................................................9在应用程序中执行 SQL 语句 .............................................................10准备语句 ...........................................................................................12游标简介 ...........................................................................................15使用游标 ...........................................................................................20选择游标类型 ....................................................................................25Adaptive Server Anywhere 游标 ..........................................................29描述结果集........................................................................................44在应用程序中控制事务......................................................................46

3 介绍数据库中的介绍数据库中的介绍数据库中的介绍数据库中的 Java.............................................................................51简介...................................................................................................52关于数据库中的 Java 的问答..............................................................55Java 讲座 ...........................................................................................62数据库中的 Java 的运行时环境 ..........................................................71教程:数据库中的 Java 练习..............................................................80

4 在数据库中使用在数据库中使用在数据库中使用在数据库中使用 Java.............................................................................89简介...................................................................................................90为数据库启用 Java......................................................................................94

iii

Page 4: Adaptive Server Anywhere

将 Java 类安装到数据库中 ...............................................................100创建要保存 Java 对象的列 ...............................................................106插入、更新和删除 Java 对象 ...........................................................108查询 Java 对象 .................................................................................114比较 Java 字段和对象 ......................................................................116数据库中 Java 类的特殊功能 ...........................................................120如何存储 Java 对象..........................................................................127Java 数据库设计 ..............................................................................130使用具有 Java 类的计算列 ...............................................................133为 Java 配置内存 .............................................................................136

5 使用使用使用使用 JDBC 访问数据访问数据访问数据访问数据 .................................................................. 139JDBC 概述.......................................................................................140使用 jConnect JDBC 驱动程序 .........................................................146使用 JDBC-ODBC Bridge .........................................................................151建立 JDBC 连接...............................................................................153使用 JDBC 访问数据 .......................................................................161创建分布式应用程序 .......................................................................170

6 嵌入式嵌入式嵌入式嵌入式 SQL 编程编程编程编程 ........................................................................ 177简介 ................................................................................................178示例嵌入式 SQL 程序 ......................................................................186嵌入式 SQL 数据类型 ......................................................................192使用主机变量 ..................................................................................196SQL 通信区域 (SQLCA)...........................................................................204读取数据 .........................................................................................210静态和动态 SQL........................................................................................220SQL 描述符区域 (SQLDA).......................................................................225发送和检索 Long 型值 .....................................................................235使用存储过程 ..................................................................................241嵌入式 SQL 编程技巧 ......................................................................245SQL 预处理器 .................................................................................247库函数参考......................................................................................251嵌入式 SQL 命令汇总 ......................................................................270

7 ODBC 编程编程编程编程 ................................................................................ 275ODBC 简介 .....................................................................................276创建 ODBC 应用程序 ......................................................................278

iv

Page 5: Adaptive Server Anywhere

ODBC 示例......................................................................................283ODBC 句柄......................................................................................286连接到数据源 ..................................................................................290执行 SQL 语句.................................................................................294使用结果集......................................................................................299调用存储过程 ..................................................................................304处理错误 .........................................................................................306

8 数据库工具接口数据库工具接口数据库工具接口数据库工具接口 .......................................................................... 309数据库工具接口简介 .......................................................................310使用数据库工具接口 .......................................................................311DBTools 函数 ..................................................................................320DBTools 结构 ..................................................................................334DBTools 枚举类型 ...........................................................................366

9 OLE DB 和和和和 ADO 编程接口编程接口编程接口编程接口 ......................................................... 371OLE DB 介绍...................................................................................372利用 Adaptive Server Anywhere 进行 ADO 编程 ...............................374支持的 OLE DB 接口 .......................................................................382

10 Open Client 接口接口接口接口 ........................................................................ 387建立 Open Client 应用程序的要求 ....................................................388数据类型映射 ..................................................................................389在 Open Client 应用程序中使用 SQL......................................................392Adaptive Server Anywhere 的已知 Open Client 限制 ..........................396

11 三层计算和分布式事务三层计算和分布式事务三层计算和分布式事务三层计算和分布式事务 ............................................................... 397简介.................................................................................................398三层计算体系结构 ...........................................................................399使用分布式事务...............................................................................404在 EAServer 中使用 Adaptive Server Anywhere .....................................406

12 部署数据库和应用程序部署数据库和应用程序部署数据库和应用程序部署数据库和应用程序 ............................................................... 409部署概述 .........................................................................................410了解安装目录和文件名....................................................................412使用 InstallShield 对象和模板进行部署 ............................................416使用静默安装来部署 .......................................................................418

v

Page 6: Adaptive Server Anywhere

部署客户端应用程序 .......................................................................422部署管理工具 ..................................................................................433部署数据库服务器...........................................................................434部署嵌入式数据库应用程序 ............................................................437

13 SQL 预处理器错误消息预处理器错误消息预处理器错误消息预处理器错误消息 .............................................................. 441SQL 预处理器错误消息 (按错误消息值编索引)...........................442SQLPP 错误.....................................................................................447

索引索引索引索引............................................................................................ 465

vi

Page 7: Adaptive Server Anywhere

关于本手册关于本手册关于本手册关于本手册

主题主题主题主题 本书介绍如何使用 C、 C++ 和 Java 编程语言建立和部署数据库应用程

序。使用 Visual Basic 和 PowerBuilder 等工具的用户可以使用这些工具

提供的编程接口。

读者读者读者读者 本手册的读者为这一类应用程序开发人员:他们编写直接 使用某种 Adaptive Server Anywhere 接口的程序。

如果您使用的开发工具有自己的控制 ODBC 的数据库接口 (例如 PowerBuilder 或 Visual Basic),则不需要阅读此手册。

SQL Anywhere Studio 文档文档文档文档

本书是 SQL Anywhere 文档集中的一部分。本节介绍文档集中包含的书

及其使用方法。

SQL Anywhere Studio 文档集文档集文档集文档集

SQL Anywhere Studio 文档集包括下面这些书:

• SQL Anywhere Studio 介绍介绍介绍介绍 :这本书概述了 SQL Anywhere Studio 数据库管理和同步技术。这本书包括一些教程,分别介绍 SQL Anywhere Studio 的各个组件。

• SQL Anywhere Studio 的新功能的新功能的新功能的新功能 :这本书面向的读者是该软件旧

版本的用户。该书列出了本产品此版本和以前版本的新功能,并介绍了升级步骤。

• Adaptive Server Anywhere 入门手册入门手册入门手册入门手册 :这本书面向的读者是对关

系数据库或 Adaptive Server Anywhere 不太熟悉的用户。它介绍了

使用 Adaptive Server Anywhere 数据库管理系统的基础知识,并概

要介绍了设计、创建和使用数据库方面的内容。

• Adaptive Server Anywhere 数据库管理指南数据库管理指南数据库管理指南数据库管理指南 :这本书介绍有关运

行、管理和配置数据库方面的内容。

• Adaptive Server Anywhere SQL 用户指南用户指南用户指南用户指南 :这本书介绍如何设

计和创建数据库;如何导入、导出和修改数据;如何检索数据以及如何创建存储过程和触发器。

vii

Page 8: Adaptive Server Anywhere

• Adaptive Server Anywhere SQL 参考手册参考手册参考手册参考手册 :这本书给 Adaptive Server Anywhere 使用的 SQL 语言提供了一套完整的参考资料。书

中还介绍了 Adaptive Server Anywhere 系统表和过程。

• Adaptive Server Anywhere 编程指南编程指南编程指南编程指南 :这本书介绍如何使用 C、C++ 和 Java 编程语言创建和部署数据库应用程序。使用 Visual Basic 和 PowerBuilder 等工具的用户可以使用这些工具提供的编程

接口。

• Adaptive Server Anywhere 错误消息错误消息错误消息错误消息 :这本书提供了 Adaptive Server Anywhere 错误消息及其诊断信息的完整列表。

• Adaptive Server Anywhere C2 安全性补充说明安全性补充说明安全性补充说明安全性补充说明 :Adaptive Server Anywhere 7.0 荣获美国政府授予的 TCSEC (可信计算机系统评估

标准) C2 安全等级。对于那些希望以相当于 C2 认证环境的方式

运行当前版本的 Adaptive Server Anywhere 的用户,他们可能会对

这本书很感兴趣。这本书未 讲述该产品获得认证后新增的安全特

性部分。

• MobiLink 同步技术用户指南同步技术用户指南同步技术用户指南同步技术用户指南 :这本书介绍用于移动计算的 MobiLink 数据同步系统的各个方面,此系统支持在单个 Oracle、Sybase、Microsoft 或 IBM 数据库与多个 Adaptive Server Anywhere 或 UltraLite 数据库之间共享数据。

• SQL Remote 用户指南用户指南用户指南用户指南 :这本书介绍用于移动计算的 SQL Remote 数据复制系统的各个方面,此系统支持在单个 Adaptive Server Anywhere 或 Adaptive Server Enterprise 数据库与多

个 Adaptive Server Anywhere 数据库之间共享数据 (使用电子邮件

或文件传输等间接链接)。

• UltraLite 用户指南用户指南用户指南用户指南 :这本书介绍如何使用 Adaptive Server Anywhere 数据库的 UltraLite 部署技术为小型设备(例如手持式管

理器)创建数据库应用程序。

• UltraLite User's Guide for PenRight! MobileBuilder :这本书面

向的读者是 PenRight!MobileBuilder 开发工具的用户。书中介绍了

如何在 MobileBuilder 编程环境中使用 UltraLite 技术。

• SQL Anywhere Studio 帮助帮助帮助帮助 :这本书仅提供联机版本。书中包含 Sybase Central、 Interactive SQL 和其它图形工具的上下文相关帮

助。

viii

Page 9: Adaptive Server Anywhere

除本文档集外, SQL Modeler 和 InfoMaker 还有自己的联机文档。

文档格式文档格式文档格式文档格式 SQL Anywhere Studio 按下列形式提供文档:

• 联机手册联机手册联机手册联机手册 :这些联机手册包含完整的 SQL Anywhere Studio 文档,其中包括印刷手册的联机版本和 SQL Anywhere 工具的上下文

相关帮助。每次发布产品的维护版本时都会对联机手册进行更新,因此这些手册是 全和 新的文档来源。

若要在 Windows 操作系统中访问联机手册,请选择 " 开始 " → "程序 " → "Sybase SQL Anywhere 8" → " 联机手册 "。可以使用左

窗格中的 HTML 帮助目录、索引和搜索功能以及右窗格中的链接

和菜单来导航联机手册。

若要在 UNIX 操作系统中访问联机手册,请在命令提示符下运行

下面的命令:

dbbooks

• 可打印手册可打印手册可打印手册可打印手册 :以一组 PDF 文件的形式提供的 SQL Anywhere 手册,可以使用 Adobe Acrobat Reader 进行查看。

CD ROM 上的 pdf_docs 目录中包含这些 PDF 文件。在运行安装

程序时,可以选择安装这些文件。

• 印刷手册印刷手册印刷手册印刷手册 :下面这些书随 SQL Anywhere Studio 一起提供:

• SQL Anywhere Studio 介绍。

• Adaptive Server Anywhere 入门手册。

• SQL Anywhere Studio 快速参考手册。这本书只有印刷版本。

SQL Anywhere 整套文档集可在 Sybase 销售部门或 Sybase 网上商

店 e-Shop 购买,网址是:http://e-shop.sybase.com/eshop。

文档约定文档约定文档约定文档约定 本节列出了文档中使用的印刷和图形约定。

语法约定语法约定语法约定语法约定 在 SQL 语法说明中,使用了以下约定:

• 关键字关键字关键字关键字 :所有 SQL 关键字的显示方式与以下示例中的 ALTER TABLE 类似:

ix

Page 10: Adaptive Server Anywhere

ALTER TABLE [ owner.]table-name

• 占位符占位符占位符占位符 :必须替换为相应的标识符或表达式的项,其显示方式与

以下示例中的 owner 和 table-name 类似。

ALTER TABLE [ owner.]table-name

• 重复项重复项重复项重复项 :对于重复项列表,只显示列表中的一个元素,后跟省略

号 (三个句点),如以下示例中的 column-constraint:

ADD column-definition [ column-constraint, … ]

允许指定一个或多个列表元素。如果指定了多个元素,则必须用逗号将它们隔开。

• 可选部分可选部分可选部分可选部分 :语句的可选部分放在方括号内。

RELEASE SAVEPOINT [ savepoint-name ]

上面的方括号表示 savepoint-name 是可选的。不应键入方括号。

• 选项选项选项选项 :如果不必选择项目列表的项目或者只能选中一个,则用垂

直条分隔这些项目,并将列表放在方括号内。

[ ASC | DESC ]

例如,可以从 ASC、 DESC 中任选一个,或者一个也不选。不应

键入方括号。

• 二选一选项二选一选项二选一选项二选一选项 :如果必须明确选择一个选项,则将替换选项放在大

括号内。

[ QUOTES { ON | OFF } ]

如果选择了 QUOTES 选项,则必须提供 ON 和 OFF 两者之一。不

应键入方括号和大括号。

• 一个或多个选项一个或多个选项一个或多个选项一个或多个选项 :如果选择多个选项,则用逗号将选项隔开。

{ CONNECT, DBA, RESOURCE }

图标图标图标图标 本文档中使用了下列图标:

x

Page 11: Adaptive Server Anywhere

图标图标图标图标 含义含义含义含义

客户应用程序。

数据库服务器,例如 Sybase Adaptive Server Anywhere 或 Adaptive Server Enterprise。

UltraLite 应用程序和数据库服务器。在 UltraLite 中,

数据库服务器和应用程序是同一过程的组成部分。

数据库。在某些高级别的图中,可以使用此图标表示数据库和管理数据库的数据库服务器。

复制或同步中间件。用于在数据库之间共享数据。例如, MobiLink Synchronization Server、 SQL Remote Message Agent 以及用于 Replication Server 的复制代理 (Log Transfer Manager) 都是中间件。

xi

Page 12: Adaptive Server Anywhere

Adaptive Server Anywhere 示例数据示例数据示例数据示例数据

库库库库

文档中的许多示例都使用 Adaptive Server Anywhere 示例数据库。

该示例数据库包含在名为 asademo.db 的文件中,并位于 SQL Anywhere 目录中。

Sybase Replication Server。

编程接口。

图标图标图标图标 含义含义含义含义

API

xii

Page 13: Adaptive Server Anywhere

该示例数据库是一家小公司的数据库。其中包含公司的内部信息 (雇员、部门和财务信息)、产品信息和销售信息 (销售订单、客户和合同)。数据库中的所有信息都是虚构的。

下图显示该示例数据库中的表以及这些表之间的相互关系。

查找更多信息并提供查找更多信息并提供查找更多信息并提供查找更多信息并提供反馈反馈反馈反馈

我们欢迎您就本文档提出意见、建议或其它反馈信息。

您可以通过新闻组 (为讨论 SQL Anywhere 技术而建立的)就本文档提

供反馈信息。可以在 forums.sybase.com 新闻服务器上找到这些新闻

组。

这些新闻组包括:

• sybase.public.sqlanywhere.general。

• sybase.public.sqlanywhere.linux。

• sybase.public.sqlanywhere.mobilink。

id = id

id = prod_id

code = fin_code_id

emp_id = sales_rep

id = cust_id

code = code

dept_id = dept_idemp_id = dept_head_id

contactid <pk> integerlast_name char(15)first_name char(15)title char(2)street char(30)city char(20)state char(2)zip char(5)phone char(10)fax char(10)

customerid <pk> integerfname char(15)lname char(20)address char(35)city char(20)state char(2)zip char(10)phone char(12)company_name char(35)

sales_orderid <pk> integercust_id <fk> integerorder_date datefin_code_id <fk> char(2)region char(7)sales_rep <fk> integer

fin_codecode <pk> char(2)type char(10)description char(50)

fin_datayear <pk> char(4)quarter <pk> char(2)code <pk,fk> char(2)amount numeric(9)

productid <pk> integername char(15)description char(30)size char(18)color char(6)quantity integerunit_price numeric(15,2)

sales_order_itemsid <pk,fk> integerline_id <pk> smallintprod_id <fk> integerquantity integership_date date

employeeemp_id <pk> integermanager_id integeremp_fname char(20)emp_lname char(20)dept_id <fk> integerstreet char(40)city char(20)state char(4)zip_code char(9)phone char(10)status char(1)ss_number char(11)salary numeric(20,3)start_date datetermination_date datebirth_date datebene_health_ins char(1)bene_life_ins char(1)bene_day_care char(1)sex char(1)

departmentdept_id <pk> integerdept_name char(40)dept_head_id <fk> integer

asademo.db

xiii

Page 14: Adaptive Server Anywhere

• sybase.public.sqlanywhere.product_futures_discussion。

• sybase.public.sqlanywhere.replication。

• sybase.public.sqlanywhere.ultralite。

新闻组免责声明新闻组免责声明新闻组免责声明新闻组免责声明iAnywhere Solutions 没有义务为其新闻组提供解决方案、信息或建议;

除提供系统操作员监控服务和确保新闻组的运行和可用性外,iAnywhere Solutions 没有义务提供任何其它服务。

如果时间允许, iAnywhere Solutions 技术顾问和其它员工也会提供新闻

组服务。他们是在自愿的基础上提供帮助,并且不能定期提供解决方案和信息。他们可以提供多少帮助取决于他们的工作量。

xiv

Page 15: Adaptive Server Anywhere

第 1 章

编程接口概述编程接口概述编程接口概述编程接口概述

关于本章关于本章关于本章关于本章 本章介绍 Adaptive Server Anywhere 的各个编程接口。任何客户端应用

程序都是使用其中的一种接口来与数据库进行通信的。

1

Page 16: Adaptive Server Anywhere

ODBC 编程接口

ODBC 编程接口编程接口编程接口编程接口

ODBC (开放式数据库连接)是 Microsoft 开发的一个标准调用层接口 (CLI)。它基于 "SQL 访问组 CLI" 规范。可以对任何提供 ODBC 驱动程

序的数据源运行 ODBC 应用程序。如果您希望应用程序能够向拥有 ODBC 驱动程序的其它数据源移植,则应使用 ODBC。此外,如果您喜

欢使用 API,则也应使用 ODBC。

ODBC 是低层接口,大致与 " 嵌入式 SQL" 相同。几乎所有的 Adaptive Server Anywhere 功能都可用于此接口。 ODBC 在 Windows 操作系统

(除 Windows CE 以外)中作为 DLL 来使用。在 UNIX 中则以库的形式

提供的。

ODBC 的主要文档是 "Microsoft ODBC 软件开发工具包 "。本书针对 Adaptive Server Anywhere 又进一步为 ODBC 开发人员提供了一些说明。

""ODBC 编程 " 第 275 页 " 中对 ODBC 作了介绍。

2

Page 17: Adaptive Server Anywhere

第 1 章 编程接口概述

OLE DB 编程接口编程接口编程接口编程接口

OLE DB 是 Microsoft 开发的一组 " 组件对象模型 "(COM) 接口,它们为

应用程序访问不同数据源中数据提供了统一访问接口,并且还提供了实现其它数据库服务的能力。这些接口支持的 DBMS 功能多少与 DBMS 相符,使数据存储能够共享它的数据。

ADO 是通过 OLE DB 系统接口以编程方式访问、编辑以及更新各种各

样的数据源的对象模型。 ADO 也是由 Microsoft 开发的。大多数使用 OLE DB 编程接口的开发人员在使用该编程接口时都是编写 ADO API 代码,而不是直接编写 OLE DB API 代码。

Adaptive Server Anywhere 中附带了一个供 OLE DB 和 ADO 程序员使用

的 OLE DB 提供程序。

关于 OLE DB 和 ADO 编程的主要文档是 Microsoft Developer Network。本书针对 Adaptive Server Anywhere 又进一步为 OLE DB 和 ADO 开发人

员提供了一些说明。

有关详细信息,请参阅 ""OLE DB 和 ADO 编程接口 " 第 371 页 "。

3

Page 18: Adaptive Server Anywhere

" 嵌入式 SQL" 编程接口

" 嵌入式嵌入式嵌入式嵌入式 SQL" 编程接口编程接口编程接口编程接口

" 嵌入式 SQL" 是一种将 SQL 命令直接嵌入在 C 或 C++ 源文件中的系

统。预处理器将这些语句翻译为对运行时库的调用。 " 嵌入式 SQL" 是一种 ISO/ANSI 和 IBM 标准。

" 嵌入式 SQL" 能够向其它数据库和其它环境移植,并且它在各种操作

环境中的功能是相等的。它可提供某种数据库产品的所有可用功能。" 嵌入式 SQL" 使用起来十分简单,不过,还是需要花一点时间来熟悉 C 代码中的 " 嵌入式 SQL" 语句 (而不是函数调用)的概念。

"" 嵌入式 SQL 编程 " 第 177 页 " 对 " 嵌入式 SQL" 作了介绍。

4

Page 19: Adaptive Server Anywhere

第 1 章 编程接口概述

JDBC 编程接口编程接口编程接口编程接口

JDBC 是 Java 应用程序的调用层接口。 JDBC 是由 Sun Microsystems 开发的,它给 Java 程序员提供了与各种关系数据库的统一接口,并且为

创建各种更高级别的工具和接口提供了一个公共基础。 JDBC 现在已经

是 Java 的标准组成部分,包括在 JDK 中。

SQL Anywhere Studio 包括一个纯 Java 的 JDBC 驱动程序,名为 Sybase jConnect。它还包括一个 JDBC-ODBC Bridge。在 "" 使用 JDBC 访问数

据 " 第 139 页 " 中对这两个程序进行了说明。有关选择驱动程序的信

息,请参阅 "" 选择 JDBC 驱动程序 " 第 141 页 "。

除了将 JDBC 用作客户端应用程序编程接口外,您还可以在数据库服务

器内使用 JDBC 从数据库中的 Java 访问数据。因此, JDBC 在数据库文

档中被作为 Java 的一部分来讲述。

本书没有讲述 JDBC。有关 JDBC 的说明,请参阅 "" 使用 JDBC 访问数

据 " 第 139 页 "。

5

Page 20: Adaptive Server Anywhere

Open Client 编程接口

Open Client 编程接口编程接口编程接口编程接口

Sybase Open Client 为客户应用程序、第三方产品以及其它 Sybase 产品

提供了与 Adaptive Server Anywhere 和其它 Open Server 进行通信所需要

的接口。

何时使用何时使用何时使用何时使用 Open Client

如果您对 Adaptive Server Enterprise 的兼容性感到担心,或者您要使用

其它支持 Open Client 接口的 Sybase 产品 (如 Replication Server),那

么您应考虑使用 Open Client 接口。

""Open Client 接口 " 第 387 页 " 中对 Open Client 接口作了介绍。 有关 Open Client 接口的更多信息,请参阅 "ASA 数据库管理指南 > 将 Adaptive Server Anywhere 用作 Open Server"。

Open Client 体系结构体系结构体系结构体系结构

Open Client 可以说是由两个组件构成的:编程接口和网络服务。

Client Library 和和和和 DB-Library

Open Client 为编写客户端应用程序提供了两个核心编程接口:DB-Library 和 Client-Library。

Open Client DB-Library 为较旧的 Open Client 应用程序提供支持,它是

一种与 Client-Library 完全不同的编程接口。 Sybase Open Client 产品附

带的《Open Client DB-Library/C 参考手册》中对 DB-Library 作了介绍。

Client-Library 程序也依赖于 CS-Library ;在 Client-Library 和 Server-Library 应用程序中都使用 CS-Library 提供的例程。 Client-Library 应用

程序还可以使用 Bulk-Library 中的例程来完成数据的高速传输。

CS-Library 和 Bulk-Library 都包括在 Sybase Open Client 中;可以将两者

分开来使用。

网络服务网络服务网络服务网络服务 Open Client 网络服务包括 Sybase Net-Library, Sybase Net-Library 支持

特定的网络协议(如 TCP/IP 和 DECnet)。应用程序的编程人员看不到 Net-Library 接口。然而,在某些平台上,对于不同的系统网络配置,应

用程序可能需要不同的 Net-Library 驱动程序。根据您的主机平台,

Net-Library 驱动程序可能由系统的 Sybase 配置指定或者在您编译和链

接程序时指定。

6

Page 21: Adaptive Server Anywhere

第 1 章 编程接口概述

有关驱动程序配置的说明,参见 《Open Client/Server 配置指南》。

有关创建 Client-Library 程序的说明,参见 《Open Client/Server 程序员

补充材料》。

7

Page 22: Adaptive Server Anywhere

Open Client 编程接口

8

Page 23: Adaptive Server Anywhere

第 2 章

在应用程序中使用在应用程序中使用在应用程序中使用在应用程序中使用 SQL

关于本章关于本章关于本章关于本章 数据库应用程序开发的许多方面取决于您的应用程序开发工具、数据库接口以及编程语言,但也有一些共同的问题和原则会影响数据库应用程序开发的多个方面。

本章讲述了适用于大多数或所有接口的一些共同的原则和技术,并提供了详细信息的线索。本章并未提供使用任何一个接口进行编程的详细指导。

9

Page 24: Adaptive Server Anywhere

在应用程序中执行 SQL 语句

在应用程序中执行在应用程序中执行在应用程序中执行在应用程序中执行 SQL 语句语句语句语句

在应用程序中使用 SQL 语句的方式取决于您使用的应用程序开发工具

和编程接口。

• ODBC 如果您直接对 ODBC 编程接口编写代码,那么您的 SQL 语句将以函数调用的形式出现。例如,下面的 C 函数调用将执行 DELETE 语句:

SQLExecDirect( stmt, "DELETE FROM employee WHERE emp_id = 105", SQL_NTS );

• JDBC 如果要使用 JDBC 编程接口,那么您可以通过调用 statement 对象的方法来执行 SQL 语句。例如,

stmt.executeUpdate( "DELETE FROM employee WHERE emp_id = 105" );

• 嵌入式嵌入式嵌入式嵌入式 SQL 如果您使用嵌入式 SQL,那么应在 C 语言 SQL 语句前用关键字 EXEC SQL 作为前缀。然后,代码在编译之前通过

预处理器处理。例如,

EXEC SQL EXECUTE IMMEDIATE 'DELETE FROM employee WHERE emp_id = 105';

• Sybase Open Client 如果要使用 Sybase Open Client 接口,那么您

的 SQL 语句以函数调用形式出现。例如,下面的一对调用将执行 DELETE 语句:

ret = ct_command(cmd, CS_LANG_CMD, "DELETE FROM employee WHERE emp_id=105" CS_NULLTERM, CS_UNUSED);ret = ct_send(cmd);

• 应用程序开发工具应用程序开发工具应用程序开发工具应用程序开发工具 应用程序开发工具(例如, Sybase Enterprise Application Studio 软件包中的软件)提供了它们自己的 SQL 对象,

这些对象在其背后使用 ODBC (PowerBuilder) 或 JDBC (Power J)。

10

Page 25: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

有关如何在应用程序中使用 SQL 的更多详细信息,请参阅您的开发工

具文档。如果要使用 ODBC 或 JDBC,则请查阅软件开发工具包中有关

这些接口的信息。

有关嵌入式 SQL 编程的详细说明,请参阅 "" 嵌入式 SQL 编程 " 第 177页 "。

服务器内的应用程序服务器内的应用程序服务器内的应用程序服务器内的应用程序 在许多方面,存储过程和触发器都充当在服务器内运行的应用程序或应用程序的组成部分。您也可以在存储过程中使用许多这里的技术。存储过程使用语句的方式与嵌入式 SQL 语句非常相似。

有关存储过程和触发器的更多信息,请参阅 "ASA SQL 用户指南 > 使用

过程、触发器和批处理 "。

数据库中的 Java 类可以采用与服务器之外的 Java 应用程序同样的方式

来使用 JDBC 接口。本章讨论了 JDBC 的一些方面。有关使用 JDBC 的其它信息,请参阅 "" 使用 JDBC 访问数据 " 第 139 页 "。

11

Page 26: Adaptive Server Anywhere

准备语句

准备语句准备语句准备语句准备语句

每次向数据库发送语句时,服务器必须首先 " 准备准备准备准备 " 语句。准备语句可

以包括:

• 语法分析语句并将它转换为内部形式。

• 例如,通过检查查询中所指的列是否确实存在,来验证对数据库

对象的所有引用的正确性。

• 如果语句涉及连接或子查询,则导致查询优化器生成访问计划。

• 在所有的这些步骤都已经执行之后,执行该语句。

重复使用准备好的语重复使用准备好的语重复使用准备好的语重复使用准备好的语句可以改善性能句可以改善性能句可以改善性能句可以改善性能

如果您发现自己要反复使用同一语句,例如,在表中插入多行,那么重复准备语句会产生很大的不必要的开销。为消除这种开销,一些数据库编程接口提供了使用准备好的语句的方法。 " 准备好的语句准备好的语句准备好的语句准备好的语句 " 是包含一

系列占位符的语句。当您要执行语句时,您所要做的只是给占位符赋值,而不是再次重新准备整个语句。

使用准备好的语句在执行多个类似的操作 (如插入多行)时特别有用。

一般来讲,使用准备好的语句需要执行下面的步骤:

1. 准备语句准备语句准备语句准备语句 在这一步,一般都要为语句提供一些占位符而非实际的值。

2. 反复执行准备好的语句反复执行准备好的语句反复执行准备好的语句反复执行准备好的语句 在这一步,提供每次执行语句时要使用的值。不必每次都准备该语句。

3. 删除语句删除语句删除语句删除语句 在这一步,释放与准备好的语句关联的资源。一些编程接口会自动处理此步骤。

不要准备那些只使用不要准备那些只使用不要准备那些只使用不要准备那些只使用一次的语句一次的语句一次的语句一次的语句

通常,不应该准备那些将只执行一次的语句。单独的准备和执行会产生轻微的性能损失,并且它会给应用程序带来不必要的复杂性。

然而,在一些接口中,确实需要准备一个语句以将它与游标关联。

有关游标的信息,请参阅 "" 游标简介 " 第 15 页 "。

要求准备和执行语句并不是 SQL 的组成部分,并且它们也因接口而异。

Adaptive Server Anywhere 中的每一个编程接口都提供了使用准备好的语

句的方法。

12

Page 27: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

如何使用准备好的语句如何使用准备好的语句如何使用准备好的语句如何使用准备好的语句

本节提供了如何使用准备好的语句的简短概述。总的过程都是相同的,但细节方面将因接口而异。通过将不同接口中使用准备好的语句的方式加以比较,即可看出这一点。

❖ 使用准备好的语句 (通用):使用准备好的语句 (通用):使用准备好的语句 (通用):使用准备好的语句 (通用):

1 准备语句。

2 设置 " 绑定参数绑定参数绑定参数绑定参数 ",这些参数将保存语句中的值。

3 给语句中的绑定参数赋值。

4 执行语句。

5 根据需要重复执行步骤 3 和 4。

6 完成之后删除语句。此步骤在 JDBC 是不需要的,因为 Java 的垃圾回收机制会为您处理此项工作。

❖ 使用准备好的语句 (嵌入式使用准备好的语句 (嵌入式使用准备好的语句 (嵌入式使用准备好的语句 (嵌入式 SQL):):):):

1 使用 EXEC SQL PREPARE 命令准备语句。

2 给语句中的参数赋值。

3 使用 EXE SQL EXECUTE 命令执行语句。

4 使用 EXEC SQL DROP 命令释放与该语句关联的资源。

❖ 使用准备好的语句使用准备好的语句使用准备好的语句使用准备好的语句 (ODBC)::::

1 使用 SQLPrepare 来准备语句。

2 使用 SQLBindParameter 绑定语句参数。

3 使用 SQLExecute 执行语句。

4 使用 SQLFreeStmt 删除语句。

13

Page 28: Adaptive Server Anywhere

准备语句

有关更多信息,请参阅 "" 执行 prepared 语句 " 第 296 页 " 和 ODBC SDK 文档。

❖ 使用准备好的语句使用准备好的语句使用准备好的语句使用准备好的语句 (JDBC)::::

1 使用连接对象的 prepareStatement 方法准备语句。这样就会返

回准备好的语句对象。

2 使用准备好的语句对象的 setType 方法设置语句参数。这里的 Type 是指定的数据类型。

3 使用准备好的语句对象的适当的方法来执行语句。对于插入、更新和删除,要使用 executeUpdate 方法。

有关在 JDBC 中使用准备好的语句的更多信息,请参阅 "" 使用 prepared 语句进行更有效的访问 " 第 166 页 "。

❖ 使用准备好的语句使用准备好的语句使用准备好的语句使用准备好的语句 (Open Client)::::

1 使用 ct_dynamic 函数并使用 CS_PREPARE 类型参数准备语

句。

2 使用 ct_param 设置语句参数。

3 使用 ct_dynamic 并使用 CS_EXECUTE 类型参数执行语句。

4 使用 ct_dynamic 并使用 CS_DEALLOC 类型参数来释放与语句

关联的资源。

有关在 Open Client 中使用准备好的语句的更多信息,请参阅 ""在 Open Client 应用程序中使用 SQL" 第 392 页 "。

14

Page 29: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

游标简介游标简介游标简介游标简介

当您在应用程序中执行查询时,结果集由许多行组成。通常,您执行查询之前并不知道应用程序要接收多少行。游标提供了在应用程序中处理查询结果集的方式。

您使用游标的方式,以及您可以使用的游标的种类,取决于您使用的编程接口。 JDBC 1.0 提供了结果集的基本处理,而 ODBC 和嵌入式 SQL 有许多不同类型的游标。 Open Client 游标只能在结果集中向前移动。

您可以利用游标在任何编程接口内执行下面的任务:

• 在查询的结果内循环。

• 在结果集内的任何点的基础数据上执行插入、更新和删除。

此外,一些编程接口可使您使用特殊功能调整结果集返回到应用程序的方式,为您的应用程序提供了实实在在的性能优点。

有关可通过不同编程接口使用的游标种类的更多信息,请参阅 "" 游标

的可用性 " 第 25 页 "。

什么是游标?什么是游标?什么是游标?什么是游标?

" 游标游标游标游标 " 是一与结果集相关联的名称。该结果集是从 SELECT 语句或存

储过程调用获得的。

游标是结果集上的句柄。任何时候,游标在结果集内都有定义明确的位置。利用游标您可以检查并可能一次一行地操纵数据。在 Adaptive Server Anywhere 中,游标可以在查询结果中前后移动。

游标位置游标位置游标位置游标位置 游标可以位于以下位置:

• 在结果集的第一行之前。

• 在结果集的某一行上。

15

Page 30: Adaptive Server Anywhere

游标简介

• 在结果集的 后一行之后。

游标位置和结果集是在数据库服务器中维护的。客户端会一次一行或一次多行地 " 读取读取读取读取 " 行,以便显示和处理。整个结果集不需要传输到客户

端。

使用游标的优点使用游标的优点使用游标的优点使用游标的优点

数据库应用程序中不一定需要使用游标,但使用游标确实具有很多好处。其好处就在于:若不使用游标,那么要进行处理和显示时,就必须将整个结果集传输到客户端:

• 客户端内存客户端内存客户端内存客户端内存 如果结果较大,要在客户端上保存整个结果集,就

会需要更多的内存。

0

1

2

3

n ? 2

n ? 1

n

n + 1

? ? 1

?

? + 1

? + 2

?

?

?

0After last row

Before first row

Absolute rowfrom start

Absolute rowfrom end

从开始算起的绝对行号

从结尾算起的绝对行号

-n-1

-n

-n+1

-n+2

-3

-2

-1

0

0

1

2

3

n-2

n-1

n

n+1

第一行之前

后一行之前

16

Page 31: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

• 响应时间响应时间响应时间响应时间 游标可以在整个结果集汇编起来之前提供开头几行。

如果您不使用游标,那么在整个结果集全部传递过来之前,您的应用程序不会显示任何行。

• 并发控制并发控制并发控制并发控制 如果您对数据进行多次更新而不在应用程序中使用游

标,那么您必须向数据库服务器分别发送多条 SQL 语句来实施这

些更改。如果结果集在客户端查询之后又发生了更改,就有可能带来并发问题。结果,就可能会导致更新丢失。

游标作为其下数据的指针,因此会对您进行的任何更改都强制执行适当的并发约束。

使用游标的步骤使用游标的步骤使用游标的步骤使用游标的步骤

在嵌入式 SQL 中使用游标与在其它接口中使用游标不同。

❖ 使用游标 (嵌入式使用游标 (嵌入式使用游标 (嵌入式使用游标 (嵌入式 SQL):):):):

1 准备语句。

游标通常使用语句句柄而不是字符串。要使用句柄,您需要准备语句。

有关准备语句的信息,请参阅 "" 准备语句 " 第 12 页 "。

2 声明游标。

每个游标都将引用单个 SELECT 或 CALL 语句。当您声明游标

时,您应声明游标的名称和它所引用的语句。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > DECLARE CURSOR 语句 [ESQL] [SP]"。

3 打开游标。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > OPEN 语句 [ESQL] [SP]"。

在 CALL 语句的情况下,打开游标会执行查询到即将获得第一

行时为止。

17

Page 32: Adaptive Server Anywhere

游标简介

4 读取结果。

虽然简单读取操作会将游标移到结果集中的下一行,但是 Adaptive Server Anywhere 允许在结果集内进行更复杂的移动。

声明游标的方式确定了您可以使用哪些读取操作。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > FETCH 语句 [ESQL] [SP]" 和 "" 读取数据 " 第 210 页 "。

5 关闭游标。

当您用完游标之后,应将它关闭。这样就会释放其下数据所持有的任何锁。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > CLOSE 语句 [ESQL] [SP]"。

6 删除语句。

要释放与游标关联的内存以及其关联的语句,必须释放语句。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > DROP STATEMENT 语句 [ESQL]"。

❖ 使用游标 (使用游标 (使用游标 (使用游标 (ODBC、、、、 JDBC、、、、 Open Client):):):):

1 准备和执行语句。

使用该接口的常用方法执行语句。您可以准备语句,然后再执行该语句,或者也可以直接执行该语句。

2 进行测试,看一看语句是否返回结果集。

在执行创建结果集的语句时,游标被隐式打开。当游标打开之后,它位于结果集的第一行之前。

3 读取结果。

虽然简单读取操作会将游标移到结果集中的下一行,但是 Adaptive Server Anywhere 允许在结果集内进行更复杂的移动。

4 关闭游标。

18

Page 33: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

当您用完游标之后,将它关闭以释放关联的资源。

5 释放语句。

如果您使用了准备好的语句,则请释放它以回收内存。

预读行预读行预读行预读行 在某些情况下,接口库可能会隐式执行性能优化 (如预读结果),因此,客户端应用程序中的这些步骤可能不完全与软件操作一致。

19

Page 34: Adaptive Server Anywhere

使用游标

使用游标使用游标使用游标使用游标

本节讲述如何使用游标执行不同类型的操作。

游标定位游标定位游标定位游标定位

当游标打开之后,它位于结果集的第一行之前。您可以将游标移到以查询结果的开头或结尾作为参照的一个绝对位置,或者移到以当前游标位置作为参照的一个相对位置。如何更改游标位置以及可以执行什么操作的细节是受编程接口约束的。

在游标中读取的行位置的数量受整数值大小约束。您 多可以读取到第 2147483646 行,这个数字比可以在整数中保存的值小 1。在使用负数

(从末尾开始计算行数)时,您 多可以读取到的行数比整数中可保存的 大负值大 1。

您可以使用特殊定位的更新操作和删除操作来更新或删除位于游标当前位置的行。如果游标位于第一行之前或 后一行之后,那么将返回 " 没

有当前的游标行 " 错误。

游标定位问题游标定位问题游标定位问题游标定位问题 对敏感性未定型游标的插入和某些更新会导致游标定位发生问题。Adaptive Server Anywhere 不将插入的行放在游标内可预测的位置,除非

在 SELECT 语句上有 ORDER BY 子句。在某些情况下,插入行在游标

关闭并再次打开之前根本不出现。

使用 Adaptive Server Anywhere 时,如果需要创建工作表来打开游标,

就会发生这种情况 (有关说明,请参阅 "ASA SQL 用户指南 > 监控和

提高性能 > 在查询处理中使用工作表 ")。

UPDATE 语句可能导致行在游标中移动。如果游标有使用现有索引的 ORDER BY 子句 (不必创建工作表),会发生这种情况。使用 STATIC SCROLL 游标会缓解这些问题,但需要更多的内存和处理。

20

Page 35: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

在打开时配置游标在打开时配置游标在打开时配置游标在打开时配置游标

您可以在打开游标时配置游标行为的以下几个方面:

• 隔离级别隔离级别隔离级别隔离级别 您可以将游标上操作的隔离级别显式设置为不同于事

务的当前隔离级别。为此,请设置 ISOLATION_LEVEL 选项。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 > ISOLATION_LEVEL 选项 [compatibility]"。

• 保存保存保存保存 缺省情况下,嵌入式 SQL 中的游标在事务结束时关闭。游

标 WITH HOLD 打开之后,您可以让它保持打开状态,直到连接结

束,或者,直到您将它显式关闭。缺省情况下, ODBC、 JDBC 和 Open Client 在事务结束时会让游标保持打开状态。

通过游标读取行通过游标读取行通过游标读取行通过游标读取行

使用游标处理查询的结果集的 简单方式是在结果集的所有行中循环,直到没有行为止。

❖ 在结果集的行中循环:在结果集的行中循环:在结果集的行中循环:在结果集的行中循环:

1 声明和打开游标 (嵌入式 SQL),或者执行返回结果集的语句

(ODBC、 JDBC、 Open Client)。

2 继续读取下一行,直到您得到 " 未找到行 " 错误。

3 关闭游标。

此操作的步骤 2 如何执行取决于您使用的接口。例如,

• ODBC SQLFetch、、、、 SQLExtendedFetch 或 SQLFetchScroll 让游

标前进到下一行并返回数据。

有关在 ODBC 中使用游标的更多信息,请参阅 "" 使用结果集 " 第299 页 "。

• 嵌入式嵌入式嵌入式嵌入式 SQL FETCH 语句执行相同的操作。

21

Page 36: Adaptive Server Anywhere

使用游标

有关在嵌入式 SQL 中使用游标的更多信息,请参阅 "" 在嵌入式 SQL 中使用游标 " 第 211 页 "。

• JDBC ResultSet 对象的 next 方法让游标前进并返回数据。

有关在 JDBC 中使用 ResultSet 对象的更多信息,请参阅 "" 使用 JDBC 的查询 " 第 165 页 "。

• Open Client ct_fetch 函数将游标前进到下一行并返回数据。

有关在 Open Client 应用程序中使用游标的更多信息,请参阅 "" 使用游标 " 第 393 页 "。

读取多行读取多行读取多行读取多行

本节讨论了一次读取多行这种方式是怎样改善性能的。

请不要将多行读取与下一节介绍的预读行混淆。多行读取由应用程序执行,而预读则不通过应用程序,但却可以提供类似的性能改进。

多行读取多行读取多行读取多行读取 某些接口提供了一次将多行读取到数组中的下几个字段的方法。通常,您执行单独的读取操作越少,服务器必须响应的单个请求也就越少,性能也就越好。修改后的检索多行的 FETCH 语句有时也称为 " 宽读取宽读取宽读取宽读取 "。使用多行读取的游标有时称为 " 块状游标块状游标块状游标块状游标 " 或 " 胖游标胖游标胖游标胖游标 "。

使用多行读取使用多行读取使用多行读取使用多行读取 • 在 ODBC 中,您可以通过设置 SQL_ROWSET_SIZE 属性来设置

每一次调用 SQLFetchScroll 或 SQLExtendedFetch 返回的行数。

• 在嵌入式 SQL 中, FETCH 语句使用 ARRAY 子句控制一次读取

的行数。

• Open Client 和 JDBC 不支持多行读取。但它们可以使用预读。

用可滚动游标读取用可滚动游标读取用可滚动游标读取用可滚动游标读取

ODBC 和嵌入式 SQL 提供了使用可滚动游标和动态可滚动游标的方法。

这些方法使您能够一次向前移动多行,或在结果集中往回移动。

JDBC 和 Open Client 接口不支持可滚动游标。

22

Page 37: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

预读不适用于可滚动操作。例如,读取相反方向中的行并不能预读前面的多行。

通过游标修改行通过游标修改行通过游标修改行通过游标修改行

游标的用途不仅仅是从查询中读取结果集。您还可以在处理游标时修改数据库中的数据。这些操作通常称为 " 定位定位定位定位 " 更新和删除操作,或者如

果操作是插入操作,则称为 "PUT" 操作。

并非所有的查询结果集都允许定位更新和删除。如果您在不可更新的视图上执行查询,则基表不会发生更改。此外,如果查询涉及连接,则必须指定您希望从哪一个表删除,或者您希望更新哪些列,何时执行操作。

只有在表中的某些非插入列允许 NULL 或有缺省值的情况下,才能通过

游标执行插入。

ODBC、嵌入式 SQL 和 Open Client 允许使用游标进行数据修改,JDBC 1.1 却不允许。对于 Open Client,您可以删除和更新行,但您只能在单

表查询上插入行。

可以从哪个表中删除可以从哪个表中删除可以从哪个表中删除可以从哪个表中删除行?行?行?行?

如果您试图通过游标执行定位删除,那么请按如下所示的方法确定从哪个表删除行:

1. 如果删除语句中未包括 FROM 子句,那么游标必须只在单个表上。

2. 如果游标用于连接查询 (包括使用包含连接的视图),则必须使用 FROM 子句。只会删除指定表的当前行,连接中涉及的其它表不会

受到影响。

3. 如果包括了 FROM 子句,但未指定表所有者,那么指定表为第一个

与其值相匹配的相关名。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > FROM 子句 "。

4. 如果给出了相关名,就用该相关名来确定指定表的名称。

5. 如果没有给出相关名,那么指定表的名称必须是游标中可明确标识的表名。

23

Page 38: Adaptive Server Anywhere

使用游标

6. 如果给出的 FROM 子句中指定了表的所有者,那么指定表的名称在

游标中对此也必须是明确可标识的表名。

7. 定位 DELETE 语句可以使用于在视图上打开的游标,只要视图是可

更新的即可。

取消游标操作取消游标操作取消游标操作取消游标操作

您可以通过接口函数取消请求。从 Interactive SQL 中,您可以通过按下

工具栏上的 " 中断 SQL 语句 " 按钮 (或者通过从 SQL 菜单中选择 " 停止 ")来取消请求。

如果您取消正在执行游标操作的请求,那么游标的位置将是不确定的。取消请求之后,您必须按照其绝对位置给游标定位,或者将它关闭。

24

Page 39: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

选择游标类型选择游标类型选择游标类型选择游标类型

本节介绍了 Adaptive Server Anywhere 游标和 Adaptive Server Anywhere 支持的编程接口所用的选项之间的映射。

有关 Adaptive Server Anywhere 游标的信息,请参阅 ""Adaptive Server Anywhere 游标 " 第 29 页 "。

游标的可用性游标的可用性游标的可用性游标的可用性

并非所有的接口都为所有的游标类型提供支持。

• ODBC 和 OLE DB (ADO) 支持所有的游标类型。

有关更多信息,请参阅 "" 使用结果集 " 第 299 页 "。

• 嵌入式 SQL 支持所有的游标类型。

• 对于 JDBC

• jConnect 4.x 只提供敏感性未定型游标。

• jConnect 5.x 支持所有类型的游标,但是可滚动游标会导致性

能严重下降。

• JDBC-ODBC Bridge 支持所有类型的游标。

• Sybase Open Client 只支持敏感性未定型游标。此外,在使用可更

新的非唯一游标时,会产生严重的性能下降。

游标属性游标属性游标属性游标属性

您可以显式或者隐式从编程接口请求游标类型。不同的接口库提供不同的游标类型选择。例如, JDBC 和 ODBC 指定了不同的游标类型。

每个游标类型都由许多特性来定义:

25

Page 40: Adaptive Server Anywhere

选择游标类型

• 唯一性唯一性唯一性唯一性 声明游标是唯一的将强制查询返回唯一地标识每一行所

需要的所有列。通常,这意味着返回主键中的所有列。所需要的但未指定的任何列都要添加到结果集中。缺省游标类型是非唯一的。

• 可更新性可更新性可更新性可更新性 声明为只读的游标不能在定位更新或删除操作中使用。

缺省游标类型是可更新的。

• 可滚动性可滚动性可滚动性可滚动性 您可以这样声明游标:当您在结果集中移动时,它表

现出不同的行为。某些游标可以只读取当前行或后面的行。其它一些游标可以在结果集中来回移动。

• 敏感性敏感性敏感性敏感性 通过游标也许可以看到对数据库的更改,也许看不到。

这些特性可能会对性能以及数据库服务器内存的使用产生明显的副作用。

Adaptive Server Anywhere 可产生具有这些特性中的各种混合特性的游

标。当您请求给定类型的游标时, Adaptive Server Anywhere 将尽可能

匹配那些特性。下面几节会详细介绍 Adaptive Server Anywhere 游标如

何匹配编程接口中指定的游标类型。

某些情况下,并非所有特性都可以提供。例如, Adaptive Server Anywhere 中的不敏感游标必须是只读的,原因将在下文中介绍。如果

您的应用程序请求可更新的不敏感游标,提供给它的将是别的类型的游标 (对值敏感)。

请求请求请求请求 Adaptive Server Anywhere 游标游标游标游标

当您从客户端应用程序请求游标类型时, Adaptive Server Anywhere 会提供一个游标。 Adaptive Server Anywhere 游标不是按照编程接口中指

定的类型进行定义的,而是按照结果集对基础数据中的更改的敏感性来定义的。 Adaptive Server Anywhere 会根据您请求的游标类型提供一个

行为与该类型游标相匹配的游标。

Adaptive Server Anywhere 按照客户端游标类型的请求来设置游标的敏感

性。

26

Page 41: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

ODBC 和和和和 OLE DB

下表说明了为响应不同的 ODBC 可滚动游标类型而设置的游标敏感性。

有关 Adaptive Server Anywhere 游标及其行为的信息,请参阅 ""Adaptive Server Anywhere 游标 " 第 29 页 "。有关如何请求 ODBC 中的游标类型的

信息,请参阅 "" 选择游标特性 " 第 299 页 "。

异常异常异常异常 如果将 STATIC 游标请求为可更新,则提供的将是对值敏感的游标,而

且会发出一个警告。

如果请求了 DYNAMIC 或 MIXED 游标,但若不使用工作表查询就无法

执行,那么就会发出警告,并改为提供敏感性未定型游标。

嵌入式嵌入式嵌入式嵌入式 SQL

要从嵌入式 SQL 应用程序请求游标,您可以在 DECLARE 语句上指定

游标类型。下表说明了为响应不同的请求设置的游标敏感性:

ODBC 可滚动游标类型可滚动游标类型可滚动游标类型可滚动游标类型 Adaptive Server Anywhere 游标游标游标游标

STATIC 不敏感

KEYSET 对值敏感

DYNAMIC 敏感

MIXED 对值敏感

游标类型游标类型游标类型游标类型 Adaptive Server Anywhere 游标游标游标游标

NO SCROLL 敏感性未定

DYNAMIC SCROLL 敏感性未定

SCROLL 对值敏感

INSENSITIVE 不敏感

SENSITIVE 敏感

27

Page 42: Adaptive Server Anywhere

选择游标类型

异常异常异常异常 如果将 DYNAMIC SCROLL 或 NO SCROLL 游标请求为 UPDATABLE,就会提供敏感的或对值敏感的游标。无法保证提供两个游标中的哪一个。这种不确定性正好符合了敏感性未定行为的定义。

如果将 INSENSITIVE 游标请求为 UPDATABLE,就会提供一个对值敏

感的游标。

如果请求 DYNAMIC SCROLL 游标,那么在 PREFETCH 数据库选项被

设置为 OFF 而且查询执行计划未涉及工作表的情况下,可能会提供敏

感的游标。同样地,这种不确定性也符合敏感性未定行为的定义。

JDBC

只有一种游标可以用于 JDBC 应用程序。这就是敏感性未定型游标。在 JDBC 中,您可以执行 ExecuteQuery 语句打开游标。

Open Client

只有一种游标可以用于 Open Client 应用程序。这就是敏感性未定型游

标。

书签和游标书签和游标书签和游标书签和游标

ODBC 提供 " 书签书签书签书签 " 或值,用于标识游标中的行。 Adaptive Server Anywhere 支持除 DYNAMIC 游标以外的其它各种游标的书签。

块状游标块状游标块状游标块状游标

ODBC 提供了一种被称为块状游标的游标类型。当您使用 BLOCK 游标

时,您可以使用 SQLFetchScroll 或 SQLExtendedFetch 读取一整块行,

而不是单行。块状游标的行为与嵌入式 SQL ARRAY 读取完全相同。

28

Page 43: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

Adaptive Server Anywhere 游标游标游标游标

任何游标一经打开,就会有一个关联的结果集。游标在一定的时间长度内保持打开状态。在这段时间内,与该游标关联的结果集可能被更改,要么是通过游标本身更改,要么是根据隔离级别要求被其它事务更改。有些游标允许看到对基础数据的更改,而其它游标却不会反映出这些更改。游标针对基础数据的更改而表现出的不同行为即是游标的" 敏感性敏感性敏感性敏感性 "。

Adaptive Server Anywhere 为游标提供了各种敏感性特性。本节介绍了什

么是敏感性,并介绍了游标的敏感性特性。

本节假设您已经阅读了 "" 什么是游标? " 第 15 页 "。

成员资格、顺序和值成员资格、顺序和值成员资格、顺序和值成员资格、顺序和值更改更改更改更改

对基础数据的更改会在下列几个方面影响游标的结果集:

• 成员资格成员资格成员资格成员资格 结果集中的行集,如它们的主键值所标识的。

• 顺序顺序顺序顺序 结果集中行的顺序。

• 值值值值 结果集中行的值。

例如,请看以下带有雇员信息的简单表 (emp_id 是主键列):

下列查询上的游标将按主键顺序返回表中的所有结果:

SELECT emp_id, emp_lnameFROM employeeORDER BY emp_id

结果集的成员资格可以通过添加新行或删除行来进行更改。值可以通过更改表中的名称来进行更改。顺序可以通过更改雇员的主键值来进行更改。

emp_id emp_lname

1 Whitney

2 Cobb

3 Chin

29

Page 44: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

可见的和不可见的更可见的和不可见的更可见的和不可见的更可见的和不可见的更改改改改

根据隔离级别要求,游标的结果集的成员资格、顺序和值可以在游标打开之后进行更改。根据所使用的游标类型不同,应用程序所看到的结果集可能会更改以反映出这些更改,也可能不会更改。

对基础数据的更改通过游标可能 " 可见可见可见可见 ",也可能 " 不可见不可见不可见不可见 "。可见的更

改是反映在游标的结果集中的更改。如果对基础数据的更改不反映在游标所看到的结果集中,那么这种更改就是不可见的。

游标敏感性概述游标敏感性概述游标敏感性概述游标敏感性概述

Adaptive Server Anywhere 游标是按其对基础数据的更改的敏感性来进行

分类的。特别是,游标敏感性是按哪些更改是可见的来定义的。

• 不敏感游标不敏感游标不敏感游标不敏感游标 当游标打开之后,结果集是固定的。对基础数据的

更改都不可见。

有关更多信息,请参阅 "" 不敏感游标 " 第 35 页 "。

• 敏感游标敏感游标敏感游标敏感游标 结果集可以在游标打开之后进行更改。对基础数据的

所有更改都是可见的。

有关更多信息,请参阅 "" 敏感游标 " 第 36 页 "。

• 敏感性未定型游标敏感性未定型游标敏感性未定型游标敏感性未定型游标 更改可能会反映在通过游标看到的结果集的

成员资格、顺序或值中,或者也可能根本没有反映。

有关更多信息,请参阅 "" 敏感性未定型游标 " 第 37 页 "。

• 对值敏感的游标对值敏感的游标对值敏感的游标对值敏感的游标 对基础数据的顺序或值的更改。当游标打开之

后结果集的成员资格是固定的。

有关更多信息,请参阅 "" 对值敏感的游标 " 第 38 页 "。

对游标的不同要求给执行设置了不同的约束,因此,对性能也会有不同的约束。有关更多信息,请参阅 "" 游标敏感性和性能 " 第 41 页 "。

游标敏感性示例:删除的行游标敏感性示例:删除的行游标敏感性示例:删除的行游标敏感性示例:删除的行

此示例使用一个简单查询来阐释这样的情形:删除结果集中的某一行后,不同的游标会如何响应。

30

Page 45: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

请看以下事件序列:

1. 一个应用程序在以下针对示例数据库的查询中打开了一个游标。

SELECT emp_id, emp_lnameFROM employeeORDER BY emp_id

2. 应用程序通过游标读取第一行 (102)。

3. 应用程序通过游标读取下一行 (105)。

4. 另外一个事务删除了 102 号雇员 (Whitney) 并提交了更改。

在此情况下游标操作的结果取决于游标敏感性:

• 不敏感游标不敏感游标不敏感游标不敏感游标 在通过游标所看到的结果的成员资格中或值中,不

反映这一 DELETE:

• 敏感游标敏感游标敏感游标敏感游标 结果集的成员资格已经更改,因此,第 105 行现在是

结果集中的第一行:

emp_id emp_lname

102 Whitney

105 Cobb

160 Breault

… …

操作操作操作操作 结果结果结果结果

读取前一行 返回行的原始副本 (102)。

读取第一行(绝对读取)

返回行的原始副本 (102)。

读取第二行(绝对读取)

返回未更改的行 (105)。

31

Page 46: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

• 对值敏感的游标对值敏感的游标对值敏感的游标对值敏感的游标 结果集的成员资格是固定的,因此行 105 仍是

结果集的第二行。 UPDATE 反映在游标的值中,并在结果集中创

建了一个有效 " 洞 "。

• 敏感性未定型游标敏感性未定型游标敏感性未定型游标敏感性未定型游标 结果集的成员资格和值在更改方面是不确定

的。读取前一行、第一行或第二行时,其响应取决于查询的特定优化方法:该方法是否涉及工作表的构造,另外,所读取的行是否已从客户端预读。

敏感性未定型游标的优点是,对于许多应用程序,敏感性是不重要的。特别是,如果您要使用只进、只读游标,将不会看到基础更改。此外,如果您要在高隔离级别运行,那么基础更改是不允许的。

游标敏感性示例:更新的行游标敏感性示例:更新的行游标敏感性示例:更新的行游标敏感性示例:更新的行

此示例使用一个简单查询阐释了这样的情形:更新了结果集中的某一行以致结果集的顺序改变时,不同的游标类型是如何响应的。

操作操作操作操作 结果结果结果结果

读取前一行 返回 " 未找到行 " 错误。没有前一行。

读取第一行 (绝对读取)

返回行 105。

读取第二行 (绝对读取)

返回行 160。

操作操作操作操作 结果结果结果结果

读取前一行 返回 " 没有当前的游标行 "。在游标中过去曾经是

第一行的地方有一个洞。

读取第一行 (绝对读取)

返回 " 没有当前的游标行 "。在游标中过去曾经是

第一行的地方有一个洞。

读取第二行 (绝对读取)

返回行 105。

32

Page 47: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

请看以下事件序列:

1. 一个应用程序在以下针对示例数据库的查询中打开了游标。

SELECT emp_id, emp_lnameFROM employee

2. 应用程序通过游标读取第一行 (102)。

3. 应用程序通过游标读取下一行 (105)。

4. 另外一个事务将 102 号雇员 (Whitney) 的员工 ID 更新为 165 并提交

更改。

在此情况下,游标操作的结果取决于游标敏感性:

• 不敏感游标不敏感游标不敏感游标不敏感游标 在通过游标看到的结果的成员资格或值中,没有反

映出这一 UPDATE:

• 敏感游标敏感游标敏感游标敏感游标 结果集的成员资格已经更改,因此,第 105 行现在是

结果集中的第一行:

emp_id emp_lname

102 Whitney

105 Cobb

160 Breault

… …

操作操作操作操作 结果结果结果结果

读取前一行 返回该行的原始副本 (102)。

读取第一行(绝对读取)

返回该行的原始副本 (102)。

读取第二行(绝对读取)

返回未更改的行 (105)。

33

Page 48: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

此外,如果该行自上次读取后已更改,那么敏感游标上的读取将返回警告 SQLE_ROW_UPDATED_WARNING。警告只发出一次。

后面再读取同一行时,不会产生警告。

同样,自上次读取某行后,如果通过游标在该行上进行定位更新或删除,就会返回 SQLE_ROW_UPDATED_SINCE_READ 错误。应

用程序必须再次读取该行才能使敏感游标上的更新或删除生效。

对任何列的更新都会导致警告 / 错误,即使该列未被游标引用也

是如此。例如,返回 emp_lname 的查询上的游标将报告更新,即使

只有 salary 列被修改也是这样。

• 对值敏感的游标对值敏感的游标对值敏感的游标对值敏感的游标 结果集的成员资格是固定的,因此行 105 仍是

结果集的第二行。 DELETE 反映在游标的值中,并在结果集中创

建了一个有效 " 洞 "。

操作操作操作操作 结果结果结果结果

读取前一行 返回 " 未找到行 "。结果集的成员资格已经更改,

因此,第 105 行现在是结果集中的第一行。游标

已经移到第一行之前的位置。

读取第一行 (绝对读取)

返回行 105。

读取第二行 (绝对读取)

返回行 160。

操作操作操作操作 结果结果结果结果

读取前一行 返回 " 未找到行 "。结果集的成员资格已经更改,

因此,现在 105 是第一行:游标位于洞上:它在

第 105 行之前。

读取第一行 (绝对读取)

返回 " 未找到行 "。结果集的成员资格已经更改,

因此,现在 105 是第一行:游标位于洞上:它在

第 105 行之前。

读取第二行 (绝对读取)

返回第 105 行。

34

Page 49: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

• 敏感性未定型游标敏感性未定型游标敏感性未定型游标敏感性未定型游标 结果集的成员资格和值在更改方面是不确定

的。读取前一行、第一行或第二行时,其响应取决于查询的特定优化方法:该方法是否涉及工作表的构造,另外,所读取的行是否已从客户端预读。

在批量操作模式下无警告或错误在批量操作模式下无警告或错误在批量操作模式下无警告或错误在批量操作模式下无警告或错误更新警告和错误情况在批量操作模式下不会发生 (-b 数据库服务器选

项)。

不敏感游标不敏感游标不敏感游标不敏感游标

这些游标具有不敏感的成员资格、顺序和值。游标打开之后进行的任何更改都是不可见的。

不敏感游标只用于只读游标类型。

标准标准标准标准 不敏感游标对应于不敏感游标的 ISO/ANSI 标准定义,并对应于 ODBC 静态游标。

编程接口编程接口编程接口编程接口

说明说明说明说明 不敏感游标会始终按任何可能存在的 ORDER BY 子句指定的顺序返回

与查询的选择标准匹配的行。

当游标打开之后,不敏感游标的结果集将完全作为工作表实现。这样会带来以下后果:

接口接口接口接口 游标类型游标类型游标类型游标类型 注释注释注释注释

ODBC、 OLE DB 和 ADO

静态 如果请求可更新的静态游标,则改为使用对值敏感的游标。

嵌入式 SQL INSENSITIVE 或 NO SCROLL

JDBC 不受支持

Open Client 不受支持

35

Page 50: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

• 如果结果集非常大,那么管理结果集需要的磁盘空间和内存可能

也非常大。

• 在整个结果集被汇编为工作表之前,没有行返回到应用程序。对

于复杂的查询,这可能会导致经过一段延迟后第一行才返回到应用程序。

• 后面的行可以直接从工作表读取,因此可以快速地返回。 Client Library 可以一次预读多行,从而进一步改善性能。

• 不敏感游标不会受 ROLLBACK 或 ROLLBACK TO SAVEPOINT 的影响。

敏感游标敏感游标敏感游标敏感游标

这些游标具有敏感的成员资格、顺序和值。

敏感游标可以用于只读或可更新的游标类型。

标准标准标准标准 敏感游标对应于敏感游标的 ISO/ANSI 标准定义,并对应于 ODBC 动态

游标。

编程接口编程接口编程接口编程接口

说明说明说明说明 通过游标可看到所有更改,包括通过游标以及从其它事务做出的更改。如果隔离级别较高,则可能会因锁定而隐藏一些在其它事务中做出的更改。

对游标成员资格、顺序以及所有列值的更改都是能够看到的。例如,如果敏感游标包含连接,而且,修改了某一个基表的某一个值,那么,由该基行组成的所有结果行都会显示新值。结果集成员资格和顺序可能会在每一次读取时更改。

接口接口接口接口 游标类型游标类型游标类型游标类型 注释注释注释注释

ODBC、 OLE DB 和 ADO

动态

嵌入式 SQL 敏感 当不需要工作表并且 PREFETCH 关闭

时,也响应 DYNAMIC SCROLL 游标

请求而予以提供。

36

Page 51: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

敏感游标会始终按任何可能存在的 ORDER BY 子句指定的顺序返回与

查询的选择标准匹配的行。更新可能会影响结果集的成员资格、顺序和值。

敏感游标的要求会对敏感游标的实现施加限制:

• 行不能被预读,因为对预读的行的更改将不会通过游标可见。这

可能会影响性能。

• 敏感游标必须在没有构建任何工作表的情况下实现,这是因为如

果行存储为工作表,则无法通过游标看到对这些行的更改。

• 由于存在着不能有工作表这样的限制,所以优化器选择连接方法

时也会受到限制,因而性能也可能会受到影响。

• 对于某些查询,优化器不能构建不包括工作表并会使游标敏感的

计划。

工作表通常用于对中间结果进行排序和分组。如果行可以通过索引进行访问,那么排序就不需要工作表。虽然无法准确说明都有哪些查询会使用工作表,但以下查询肯定要使用工作表:

• UNION 查询,虽然 UNION ALL 不一定使用工作表。

• 带有 ORDER BY 子句的语句,如果在 ORDER BY 列上没有

索引。

• 任何使用散列连接优化的查询。

• 许多涉及 DISTINCT 或 GROUP BY 子句的查询。

在这些情况下, Adaptive Server Anywhere 或者会向应用程序返回

错误,或者会将游标类型更改为敏感性未定型游标并返回警告。

有关查询优化和使用工作表的更多信息,请参阅 "ASA SQL 用户

指南 > 查询优化与执行 "。

敏感性未定型游标敏感性未定型游标敏感性未定型游标敏感性未定型游标

这些游标在其成员资格、顺序或值中没有明确定义的敏感性。在敏感性方面允许的这一灵活性可使敏感性未定型游标得以优化,以利于性能改善。

37

Page 52: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

敏感性未定型游标只用于只读游标类型。

标准标准标准标准 敏感性未定型游标对应于敏感性未定型游标的 ISO/ANSI 标准定义,并

对应于带有非特定敏感性的 ODBC 游标。

编程接口编程接口编程接口编程接口

说明说明说明说明 Adaptive Server Anywhere 可使用一些方法来优化查询并向应用程序返回

行,请求敏感性未定型游标并不会给这些方法带来什么限制。因此,敏感性未定型游标提供的性能 佳。特别是,对于将中间结果实现为工作表的任何措施,优化器均可自由使用,而且,客户端可以预读行。

Adaptive Server Anywhere 不保证用户能够看到对数据库基础行的更改。

某些更改可能是可见的,而另外一些是不可见的。成员资格和顺序可能会在每一次读取时都更改。特别是,对基行的更新可能会导致只有部分更新的列反映在游标的结果中。

敏感性未定型游标不能保证返回与查询的选择和顺序匹配的行。行成员资格在游标打开时是固定的,但后面对基础值的更改将反映在结果中。

敏感性未定型游标会始终返回这样的行:这些行在建立游标成员资格时匹配客户的 WHERE 和 ORDER BY 子句。如果在游标打开之后列值被

更改,那么可能返回不再匹配 WHERE 和 ORDER BY 子句的行。

对值敏感的游标对值敏感的游标对值敏感的游标对值敏感的游标

这些游标在其成员资格方面是不敏感的,而在结果集的顺序和值方面是敏感的。

对值敏感的游标可以用于只读或可更新的游标类型。

标准标准标准标准 对值敏感的游标不对应于 ISO/ANSI 标准定义。它们对应于 ODBC 键集

驱动的游标。

接口接口接口接口 游标类型游标类型游标类型游标类型

ODBC、 OLE DB 和 ADO 未指定的敏感性

嵌入式 SQL 动态滚动

38

Page 53: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

编程接口编程接口编程接口编程接口

说明说明说明说明 如果应用程序读取的行是由已经更改的数据库基础行构成的,那么,就必须给应用程序呈现更新后的值,而且必须向应用程序发出 SQL_ROW_UPDATED 状态。如果应用程序试图读取的行是由被删除的

数据库基础行构成的,那么,就必须向应用程序发出 SQL_ROW_DELETED 状态。

对主键值的更改会从结果集中删除行 (作为删除对待,后面跟插入)。当结果集中的某一行被删除 (从游标中或者游标之外)并插入带有同一主键值的一个新行时,会发生特殊情况。这将会导致在旧行出现的位置由新行替换旧行。

结果集中的行并不一定会与查询的选择或顺序指定匹配。由于行成员资格在打开时是固定的,因此,即使后面的更改使行不匹配 WHERE 子句

或 ORDER BY,这样的更改也并不会更改行的成员资格,同样也不会

更改行的位置。

所有的值对通过游标进行的更改都是敏感的。成员资格对通过游标进行的更改的敏感性受 ODBC 选项 SQL_STATIC_SENSITIVITY 的控制。如

果该选项已打开,那么通过游标的插入会将行添加到游标。否则,它们就不是结果集的组成部分。通过游标的删除将会从结果集删除行,从而可防止洞返回 SQL_ROW_DELETED 状态。

对值敏感的游标可使用 " 键集表键集表键集表键集表 "。当游标打开之后, Adaptive Server Anywhere 将用组成结果集的每一行的标识信息填充工作表。当在结果

集中滚动时,将使用键集表标识结果集的成员资格,但在必要时从基表获取值。

对值敏感的游标的固定成员资格属性可使您的应用程序记住游标内的行位置,并确保这些位置不会改变。有关更多信息,请参阅 "" 游标敏感

性示例:删除的行 " 第 30 页 "。

接口接口接口接口 游标类型游标类型游标类型游标类型

ODBC、 OLE DB 和 ADO 键集驱动

嵌入式 SQL SCROLL

JDBC 键集驱动

Open Client 键集驱动

39

Page 54: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

• 如果自从游标打开之后某一行被更新或者可能已经更新,那么 Adaptive Server Anywhere 将在读取该行时返回 SQLE_ROW_UPDATED_WARNING。警告只生成一次:再次读取

同一行将不会产生警告。

即使更新的列不被游标引用,对行的任何列的更新都会产生警告。例如,即使只有 birthdate 列被修改, emp_lname 和 emp_fname 上的

游标也将报告更新。当行锁定被禁用时,这些更新警告和错误情况在批量操作模式下不会发生 (-b 数据库服务器选项)。请参阅

"ASA SQL 用户指南 > 导入和导出数据 > 移动数据的性能考虑 "。

有关更多信息,请参阅 "ASA 错误消息 > 数据库错误消息 > 上次

读取后行已更新 "。

• 在自上次读取后被修改的行上执行定位更新或删除的尝试将会返

回 SQLE_ROW_UPDATED_SINCE_READ 错误并会取消该语句。

应用程序必须再次 FETCH 该行,然后才能允许 UPDATE 或 DELETE。

只要更新行中的列,即使游标不引用所更新的列,也会产生错误。在批量操作模式下,不会发生错误。

有关更多信息,请参阅 "ASA 错误消息 > 数据库错误消息 > 上次

读取后行已更改 -- 操作被取消 "。

• 打开游标之后,如果通过游标或从另一事务中删除了某行,游标

中就会创建一个 " 洞洞洞洞 "。由于游标的成员资格是固定的,因此,会

保留行位置,但 DELETE 操作会反映在行的更改的值中。如果您

读取此洞上的行,您会得到 " 没有当前的游标行 " 错误 (SQL 状态 24503),指出没有当前行,并且游标仍定位在该洞上。您可以通

过使用敏感游标来避免洞,因为敏感游标的成员资格会随值一起改变。

有关更多信息,请参阅 "ASA 错误消息 > 数据库错误消息 > 没有

当前的游标行 "。

对于对值敏感的游标,行不能被预读。此要求可能会在某些情况下影响性能。

40

Page 55: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

游标敏感性和性能游标敏感性和性能游标敏感性和性能游标敏感性和性能

就性能与游标的其它属性的关系而言,往往是取此必然舍彼,二者不可兼得。特别是,如果使游标成为可更新游标,就会限制游标查询处理和传递,进而影响性能。此外,对游标敏感性提出要求也可能会约束游标性能。

要理解游标的可更新性和敏感性如何影响性能,就需要理解能通过游标看到的结果是如何从数据库传输到客户端应用程序的。

特别是,结果可能会由于性能原因存储在两个中间位置:

• 工作表工作表工作表工作表 无论是中间还是 后结果都可能作为工作表存储。对值

敏感的游标会使用由主键值构成的工作表。查询特性也可能导致优化器在其选择的执行计划中使用工作表。

• 预读预读预读预读 通信的客户端可能会将许多行检索到客户端的缓冲区中,

以避免为每一行单独将请求发送到数据库服务器。

敏感性和可更新性限制了中间位置的使用。

任何可更新的游标都会被阻止使用工作表和预读结果,如果使用,那么游标将易于丢失更新内容。下面这一示例说明了此问题:

1. 某个应用程序在以下针对示例数据库的查询中打开一个游标。

SELECT id, quantityFROM product

ODBC 驱动程序或网络库 数据库服务器

预读的行

工作表

客户端应用程序

41

Page 56: Adaptive Server Anywhere

Adaptive Server Anywhere 游标

2. 应用程序通过游标读取 id = 300 的行。

3. 另外一个事务使用以下语句更新已被更新的这一行:

UPDATE productSET quantity = quantity - 10WHERE id = 300

4. 应用程序通过游标将该行更新为 (quantity - 5 ) 这样一个值。

5. 该行的正确的 终值是 13。如果游标预读了该行,那么该行的新值

是 23。另外一个事务的更新会丢失。

类似的限制也约束着敏感性。有关更多信息,请参阅有关不同游标类型的说明。

预读行预读行预读行预读行

预读和多行读取是不同的。预读可以在没有来自客户端应用程序的显式指令的情况下执行。预读会将行从服务器检索到客户端上的缓冲区中,但客户端应用程序要先读取相应的行,然后才能使用这些行。

缺省情况下,只要应用程序读取单行, Adaptive Server Anywhere Client Library 就会预读多行。 Adaptive Server Anywhere Client Library 会将其

余的行存储在缓冲区中。

预读会通过减少客户 / 服务器通信而提高性能,并且不用为每一行或行

块向服务器发送单独的请求,就可以让许多行可供使用,因而可提高吞吐量。

有关控制预读的更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 > PREFETCH 选项 [database]"。

id quantity

300 28

301 54

302 75

… …

42

Page 57: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

控制应用程序的预读控制应用程序的预读控制应用程序的预读控制应用程序的预读 • PREFETCH 选项可以控制是否发生预读。对于单个的连接,您可

以将 PREFETCH 选项设置为 ON 或 OFF。缺省情况下,它被设置

为 ON。

• 在嵌入式 SQL 中,当您使用 BLOCK 子句打开单个 FETCH 操作

上的游标时,您可以针对每个游标控制预读。

应用程序可通过指定 BLOCK 子句来指定从服务器读取一次 多

可以包含多少行。例如,如果您一次读取和显示 5 行,您可以使

用 BLOCK 5 ;如果指定 BLOCK 0,一次就会读取 1 个记录,也

会使 FETCH RELATIVE 0 总是再次从服务器读取行。

虽然您还可以通过在应用程序上设置连接参数来将预读关闭,但是设置 BLOCK=0 比设置 PREFETCH 选项为 OFF 效率更高。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 > PREFETCH 选项 [database]"。

• 在 Open Client 中,您可以在游标声明之后 (但要在它打开之

前)使用 ct_cursor 并使用 CS_CURSOR_ROWS 来控制预读行

为。

游标敏感性和隔离级别游标敏感性和隔离级别游标敏感性和隔离级别游标敏感性和隔离级别

游标敏感性和事务隔离级别都是针对并发问题,但所采取的方式不同。

通过选择事务的隔离级别 (常常在连接级别),您可以确定何时在数据库中的行上放置锁。锁可以防止其它事务访问或修改数据库中的值。

通过选择游标敏感性,您可以确定哪些更改对于使用游标的应用程序可见。通过设置游标敏感性,您并非确定何时在数据库中的行上放置锁,您也并没有限制可以对数据库本身进行的更改。

43

Page 58: Adaptive Server Anywhere

描述结果集

描述结果集描述结果集描述结果集描述结果集

有些应用程序会构建无法完全在应用程序中指定的 SQL 语句。例如,

在有些情况下,在应用程序准确知道要检索什么信息之前 (比如当某一报告应用程序让用户选择要显示的列时),语句取决于来自用户的响应。

在这样的情况下,应用程序需要用一种方法来检索关于 " 结果集结果集结果集结果集 " 的性

质及内容方面的信息。关于结果集性质的信息 (被称为 " 描述符描述符描述符描述符 ")用

于标识数据结构,包括可望返回的列的数量和类型。一旦应用程序确定了结果集的性质,检索内容的过程就简单了。

此 " 结果集元数据结果集元数据结果集元数据结果集元数据 " (关于数据的性质和内容的信息)通过使用描述符

来操纵。获取和管理结果集元数据的过程称为 " 描述描述描述描述 "。

由于游标通常会产生结果集,所以描述符和游标会紧密链接,只不过有些接口隐藏了描述符的使用,用户看不到。通常,需要描述符的语句是返回结果集的 SELECT 语句或存储过程。

与基于游标的操作一起使用描述符的顺序如下所示:

1. 分配描述符。此操作可以隐式进行,不过有些接口也允许显式分配。

2. 准备语句。

3. 描述语句。如果语句是存储过程调用或批处理,且结果集不是由过程定义中的结果子句定义的,那么描述应在打开游标之后发生。

4. 为语句声明和打开游标 (嵌入式 SQL)或执行该语句。

5. 如果有必要,获取描述符并修改分配区域。这一步通常隐式进行。

6. 读取和处理语句结果。

7. 释放描述符。

8. 关闭游标。

9. 删除语句。有些接口可以自动完成这一步。

实现注意事项实现注意事项实现注意事项实现注意事项 • 在嵌入式 SQL 中, SQLDA (SQL 描述符区域)结构将保存描述

符信息。

44

Page 59: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

有关更多信息,请参阅 ""SQL 描述符区域 (SQLDA)" 第 225 页 "。

• 在 ODBC 中,使用 SQLAllocHandle 分配的描述符句柄提供了对描

述符的字段的访问。您可以使用 SQLSetDescRec、SQLSetDescField、 SQLGetDescRec 和 SQLGetDescField 来操纵

这些字段。

或者,您还可以使用 SQLDescribeCol 和 SQLColAttributes 获取列

信息。

• 在 Open Client 中,您可以使用 ct_dynamic 来准备语句,使用 ct_describe 来描述语句的结果集。不过,您还可以使用 ct_command 来发送 SQL 语句,不必先准备它,并使用 ct_results 逐个地处理返回的行。这是在 Open Client 应用程序开发中比较常

见的操作方式。

• 在 JDBC 中, java.SQL.ResultSetMetaData 类提供了有关结果集的

信息。

• 您还可以使用描述符向引擎发送数据 (例如,使用 INSERT 语句);然而,这与用于结果集的描述符是不同种类的描述符。

有关 DESCRIBE 语句的输入和输出参数的更多信息,请参阅

"ASA SQL 参考手册 > SQL 语句 > DESCRIBE 语句 [ESQL]"。

45

Page 60: Adaptive Server Anywhere

在应用程序中控制事务

在应用程序中控制事务在应用程序中控制事务在应用程序中控制事务在应用程序中控制事务

事务是原子 SQL 语句集。要么执行事务中的所有语句,要么一个也不

执行。本节描述了应用程序中的事务的一些方面。

有关事务的更多信息,请参阅 "ASA SQL 用户指南 > 使用事务和隔离级

别 "。

设置自动提交或手动提交模式设置自动提交或手动提交模式设置自动提交或手动提交模式设置自动提交或手动提交模式

数据库编程接口可以采用 " 手动提交手动提交手动提交手动提交 " 模式或 " 自动提交自动提交自动提交自动提交 " 模式工作。

• 手动提交模式手动提交模式手动提交模式手动提交模式 只有在您的应用程序执行显式提交操作时,或者,

在数据库服务器实现自动提交时 (例如,执行 ALTER TABLE 语句或其它数据定义语句时),才提交操作。手动提交模式有时也称为 " 链接模式链接模式链接模式链接模式 "。

要在应用程序中使用事务 (包括嵌套事务和保存点),您必须在手动提交模式下操作。

• 自动提交模式自动提交模式自动提交模式自动提交模式 将每一语句都作为单独的事务对待。自动提交模

式相当于在您的每一个命令的末尾附加 COMMIT 语句。自动提交

模式有时也称为 " 非链接模式非链接模式非链接模式非链接模式 "。

自动提交模式会影响应用程序的性能和行为。如果应用程序需要事务完整性,则请不要使用自动提交。

有关自动提交对性能的影响的信息,请参阅 "ASA SQL 用户指南 > 监控

和提高性能 > 关闭自动提交模式 "。

控制自动提交行为控制自动提交行为控制自动提交行为控制自动提交行为

控制应用程序的提交行为的方式取决于您使用的编程接口。自动提交的实现可以是客户端的或服务器端的,具体情况视接口而定。

有关更多信息,请参阅 "" 自动提交实现细节 " 第 47 页 "。

46

Page 61: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

❖ 控制自动提交模式控制自动提交模式控制自动提交模式控制自动提交模式 (ODBC)::::

• 缺省情况下, ODBC 在自动提交模式下工作。关闭自动提交的

方式取决于您是在直接使用 ODBC 还是在使用应用程序开发工

具。如果要直接对 ODBC 接口编程,则请设置 SQL_ATTR_AUTOCOMMIT 连接属性。

❖ 控制自动提交模式控制自动提交模式控制自动提交模式控制自动提交模式 (JDBC)::::

• 缺省情况下, JDBC 在自动提交模式下工作。要关闭自动提

交,请使用连接对象的 setAutoCommit 方法:

conn.setAutoCommit( false );

❖ 控制自动提交模式控制自动提交模式控制自动提交模式控制自动提交模式 (Open Client)::::

• 缺省情况下,通过 Open Client 进行的连接在自动提交模式下工

作。您可以更改此行为,方法是:使用下面这样的语句在应用程序中将 CHAINED 数据库选项设置为 ON:

SET OPTION CHAINED='ON'

❖ 控制自动提交模式 (嵌入式控制自动提交模式 (嵌入式控制自动提交模式 (嵌入式控制自动提交模式 (嵌入式 SQL):):):):

• 缺省情况下,嵌入式 SQL 应用程序在手动提交模式下工作。要

启用自动提交,请使用下面这样的语句将 CHAINED 数据库选

项设置为 OFF:

SET OPTION CHAINED='OFF'

自动提交实现细节自动提交实现细节自动提交实现细节自动提交实现细节

上一节 "" 控制自动提交行为 " 第 46 页 " 描述了如何从 Adaptive Server Anywhere 每一个的编程接口控制自动提交行为。根据您使用的接口以

及控制自动提交行为的方式,自动提交模式的行为会稍有不同。

实现自动提交模式可以采用以下两种方式之一:

47

Page 62: Adaptive Server Anywhere

在应用程序中控制事务

• 客户端自动提交客户端自动提交客户端自动提交客户端自动提交 当应用程序使用自动提交时, Client Library 在每一个 SQL 语句执行之后发送 COMMIT 语句。

Adaptive Server Anywhere 对于 ODBC 和 OLE DB 应用程序将使用

客户端自动提交。

• 服务器端自动提交服务器端自动提交服务器端自动提交服务器端自动提交 当应用程序使用自动提交时,数据库服务器

在每个 SQL 语句之后发出提交。此行为在使用 JDBC 的情况下由 CHAINED 数据库选项隐式控制。

Adaptive Server Anywhere 对于嵌入式 SQL、 JDBC 和 Open Client 应用程序将使用服务器端自动提交。

在复合语句 (如存储过程或触发器)的情况下,在客户端和服务器端自动提交之间有一些区别。从客户端看,存储过程是单一语句,因此自动提交将在整个过程执行之后发送单一提交语句。从数据库服务器的角度来看,存储过程可以由许多 SQL 语句构成,因此服务器端自动提交

会在该过程内的每个 SQL 语句之后发出 COMMIT。

不要混合使用客户端和服务器端实现不要混合使用客户端和服务器端实现不要混合使用客户端和服务器端实现不要混合使用客户端和服务器端实现在 ODBC 或 OLE DB 应用程序中不要将 CHAINED 选项与自动提交结

合使用。

控制隔离级别控制隔离级别控制隔离级别控制隔离级别

可以使用 ISOLATION_LEVEL 数据库选项设置当前连接的隔离级别。

某些接口 (如 ODBC)允许您在连接时设置连接的隔离级别。以后,

您可以使用 ISOLATION_LEVEL 数据库选项将此级别复位。

游标和事务游标和事务游标和事务游标和事务

通常,当执行 COMMIT 时游标会关闭。但此行为也有两个例外:

• CLOSE_ON_ENDTRANS 数据库选项被设置为 OFF。

• 游标打开为 WITH HOLD,这是 Open Client 和 JDBC 的缺省值。

48

Page 63: Adaptive Server Anywhere

第 2 章 在应用程序中使用 SQL

如果这两种情况中任何一种为真,那么游标在 COMMIT 时依然打开。

ROLLBACK 和游标和游标和游标和游标 如果事务回退,那么游标就会关闭,那些打开为 WITH HOLD 的游标除

外。然而,回退之后不要依赖任何游标的内容。

ISO SQL3 标准草案声明:在回退时,所有游标 (甚至是那些打开为 WITH HOLD 的游标)都应关闭。您可以通过将 ANSI_CLOSE_CURSORS_AT_ROLLBACK 选项为设置 ON 来获得此行

为。

保存点保存点保存点保存点 如果事务回退到保存点,并且如果 ANSI_CLOSE_CURSORS_AT_ROLLBACK 选项为 ON,那么所有在 SAVEPOINT 后还处于打开状态的游标 (甚至是那些打开为 WITH HOLD 的游标)将关闭。

游标和隔离级别游标和隔离级别游标和隔离级别游标和隔离级别 可以使用 SET OPTION 语句来更改 ISOLATION_LEVEL 选项,以在事

务期间更改连接的隔离级别。然而,这种更改只影响关闭的游标。

49

Page 64: Adaptive Server Anywhere

在应用程序中控制事务

50

Page 65: Adaptive Server Anywhere

第 3 章

介绍数据库中的介绍数据库中的介绍数据库中的介绍数据库中的 Java

关于本章关于本章关于本章关于本章 本章介绍使用数据库中的 Java 的动机和涉及的概念。

Adaptive Server Anywhere 是 Java 的一种运行时环境。 Java 为 SQL 提供

一种自然扩展,从而将 Adaptive Server Anywhere 演变成下一代企业应

用程序的平台。

51

Page 66: Adaptive Server Anywhere

简介

简介简介简介简介

Adaptive Server Anywhere 是 "Java 的运行时环境的运行时环境的运行时环境的运行时环境 "。这意味着 Java 类可

以在数据库服务器中执行。在数据库服务器内创建 Java 类的运行时环

境,这为管理和存储数据及逻辑提供了一种功能强大的新方式。

数据库中的 Java 具有下列优点:

• 您可以在应用程序的不同层 (客户端、中间层或服务器)中重复

使用 Java 组件,并且可以在需要时随时随地用到这些 Java 组件。

Adaptive Server Anywhere 变成了一种用于分布式计算的平台。

• 对于在数据库中建立逻辑, Java 是一种比存储过程功能更强大的

语言。

• Java 类变成了丰富的用户定义的数据类型。

• Java 类的方法提供了可从 SQL 访问的新函数。

• Java 可用于数据库中,而不会危害数据库的完整性、安全性和可

靠性。

单独授予许可的组件单独授予许可的组件单独授予许可的组件单独授予许可的组件 数据库中的 Java 是单独授予许可的组件,您必须先订购然后才能安装

它。若要订购该组件,请参阅 SQL Anywhere Studio 产品包中的卡片或

者访问 http://www.sybase.com/detail?id=1015780。

SQLJ 标准标准标准标准 数据库中的 Java 基于 SQLJ 第 1 部分和 SQLJ 第 2 部分建议的标准。

SQLJ 第 1 部分提供了关于将 Java 静态方法作为 SQL 存储过程和用户定

义的函数来调用的规范。SQLJ 第 2 部分提供了关于将 Java 类用作 SQL 域的规范。

了解数据库中的了解数据库中的了解数据库中的了解数据库中的 Java

Java 是一种相对较新的编程语言,其知识库在不断增大,但仍有限。本

文档面向各种 Java 开发人员,从经验丰富的 Java 开发人员到那些对 Java 语言、用途、语法和用法都不熟悉的众多读者,每个人都可以从中

受益。

52

Page 67: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

对于那些熟悉 Java 的读者来说,在如何在数据库中使用 Java 这一方

面,有许多东西需要学习。 Adaptive Server Anywhere 不仅用 Java 扩展

了数据库的功能,而且还用数据库扩展了 Java 的功能。

Java 文档文档文档文档 下表列出了有关在数据库中使用 Java 的文档。

使用使用使用使用 Java 文档文档文档文档

下表可帮助您根据您的兴趣和背景确定 Java 文档的哪些部分适合您。

它只是一个指南,不应当以此来限制您学习更多有关在数据库中使用 Java 的内容。

标题标题标题标题 目的目的目的目的

" 介绍数据库中的 Java" 第 51 页(本章)

Java 的概念以及如何在 Adaptive Server Anywhere 应用它们。

" 在数据库中使用 Java" 第 89 页

在数据库中使用 Java 的实际步骤。

"使用 JDBC 访问数据 " 第139 页

从 Java 类访问数据,包括分布式计算。

"ASA SQL 用户指南 > 调试

数据库中的逻辑 "测试和调试在数据库中运行的 Java 代码。

Adaptive Server Anywhere 参考

该参考手册 包括有关那些支持在数据库中使

用 Java 的 SQL 扩展的材料。

Sun 的 Java API 参考指南 关于 Java API 类、字段和方法的联机指南。

仅以 Windows 帮助格式提供。

Bruce Eckel 所著的《Java 编程思想》

讲述如何用 Java 编程的联机手册。以 Adobe PDF 格式提供,位于 SQL Anywhere 目录的 Samples\ASA\Java 子目录中。

53

Page 68: Adaptive Server Anywhere

简介

如果您如果您如果您如果您 … 请考虑阅读请考虑阅读请考虑阅读请考虑阅读 …

在面向对象编程方面是新手。 "Java 讲座 " 第 62 页

Bruce Eckel 所著的《Java 编程思

想》。

需要对诸如实例化、字段和类方法之类的术语的解释。

"Java 讲座 " 第 62 页

是希望立刻开始的 Java 开发人员。 " 数据库中的 Java 的运行时环

境 " 第 71 页

" 教程:数据库中的 Java 练习 " 第 80 页

希望了解数据库中 Java 的主要特性。 " 关于数据库中的 Java 的问答 " 第 55 页

希望了解如何从 Java 访问数据。 " 使用 JDBC 访问数据 " 第 139页

希望为 Java 准备数据库。 " 为数据库启用 Java" 第 94 页

需要受支持的 Java API 的完整列表。 "ASA SQL 参考手册 > SQL 数据类

型 > Java 类数据类型 "

正在尝试使用 Java API 类并需要 Java 参考信息。

Java API 类的联机指南(仅限 Windows 帮助)

想查看分布式计算的示例。 " 创建分布式应用程序 " 第 170页

54

Page 69: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

关于数据库中的关于数据库中的关于数据库中的关于数据库中的 Java 的问答的问答的问答的问答

本节介绍数据库中的 Java 的主要功能。

数据库中的数据库中的数据库中的数据库中的 Java 有哪些主要功能?有哪些主要功能?有哪些主要功能?有哪些主要功能?

下面所有要点的详细解释将在后面的几节中提供。

• 可以在数据库服务器中运行可以在数据库服务器中运行可以在数据库服务器中运行可以在数据库服务器中运行 Java 一个内部 Java 虚拟机 (VM) 在数据库服务器中运行 Java 代码。

• 可以从可以从可以从可以从 SQL 调用调用调用调用 Java 可以从 SQL 语句调用 Java 函数 (方

法)。 Java 方法为在数据库中添加逻辑提供了一种比 SQL 存储过

程功能更强大的语言。

• 可以从可以从可以从可以从 Java 访问数据访问数据访问数据访问数据 内部 JDBC 驱动程序可让您从 Java 访问数

据。

• 可以在数据库中调试可以在数据库中调试可以在数据库中调试可以在数据库中调试 Java 可以使用 Sybase 调试程序测试和调试

数据库中的 Java 类。

• Java 类可用作数据类型类可用作数据类型类可用作数据类型类可用作数据类型 数据库中安装的每个 Java 类都可以作为

数据类型,这些数据类型可用作表中的列的数据类型或变量的数据类型。

• 可在表中保存可在表中保存可在表中保存可在表中保存 Java 对象对象对象对象 Java 类的实例 (Java 对象)可以做为表

中的值保存。您可以将 Java 对象插入表中,针对存储在表中的对

象的字段和方法执行 SELECT 语句,并从表中检索 Java 对象。

Adaptive Server Anywhere 在具备了这种功能以后就变成了对象 -关系数据库,既可以支持对象,又不会减弱现有的关系功能。

• 保留保留保留保留 SQL 使用 Java 不会改变现有 SQL 语句的行为,也不会改

变非 Java 关系数据库行为的其它方面。

55

Page 70: Adaptive Server Anywhere

关于数据库中的 Java 的问答

如何在数据库中存储如何在数据库中存储如何在数据库中存储如何在数据库中存储 Java 指令?指令?指令?指令?

Java 是一种面向对象的语言,因此其指令 (源代码)以类的形式出现。

要在数据库中执行 Java,您可以在数据库外编写 Java 指令并在数据库

外将它们编译为已编译的类 (字节代码字节代码字节代码字节代码),这些类是包含 Java 指令的

二进制文件。

然后,将这些已编译的类安装到数据库中。安装之后,便可以在数据库服务器中执行这些类了。

Adaptive Server Anywhere 是 Java 类的运行时环境,而不是 Java 开发环

境。要编写和编译 Java,您需要一个 Java 开发环境,如 Sybase PowerJ 或 Sun Microsystems Java 开发工具包 (JDK)。

有关更多信息,请参阅 " 将 Java 类安装到数据库中 " 第 100 页。

Java 在数据库中是如何执行的?在数据库中是如何执行的?在数据库中是如何执行的?在数据库中是如何执行的?

Adaptive Server Anywhere 包括一个在数据库环境中运行的 "Java 虚拟机虚拟机虚拟机虚拟机

"(VM)。 Sybase Java VM 解释已编译的 Java 指令并在数据库服务器中运

行它们。

除了 VM 外,数据库服务器中的 SQL 请求处理器也已经得到了扩展,

这样它就可以向 VM 发出调用来执行 Java 指令。另外,它还可以处理 VM 的请求以便能够从 Java 进行数据访问。

与独立与独立与独立与独立 VM 的区别的区别的区别的区别 使用标准的 VM (如 Sun Java VM java.exe)执行 Java 代码与在数据

库中执行 Java 代码之间有一个区别。 Sun VM 是从命令行运行的,而 Adaptive Server Anywhere Java VM 作为 SQL 语句执行过程的一部分,

随时都可用于执行 Java 操作。

Sybase Java 解释器不能从外部访问,只有在 SQL 语句的执行过程需要 Java 操作的情况下才使用它。在数据库服务器需要 VM 时将自动启动 VM,您不必采取任何显式操作以启动或停止 VM。

56

Page 71: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

为什么用为什么用为什么用为什么用 Java????

Java 具有的许多功能使得它非常适合用在数据库中,这些功能包括:

• 编译时全面错误检查。

• 具有定义明确的错误处理方法的内置错误处理。

• 内置的垃圾回收 (内存恢复)。

• 摈弃了许多容易出错的编程技术。

• 强大的安全功能。

• Java 代码是解释执行的,因此任何操作如果不被 VM 接受,都将

无法执行。

哪些平台支持数据库中的哪些平台支持数据库中的哪些平台支持数据库中的哪些平台支持数据库中的 Java????

Windows CE 中不支持数据库中的 Java,但其它 Windows 操作系统、

UNIX 和 NetWare 都支持。

如何结合使用如何结合使用如何结合使用如何结合使用 Java 和和和和 SQL????

数据库中 Java 的设计指导原则是:它要为现有的 SQL 功能提供自然

的、开放的扩展。

• Java 操作可从操作可从操作可从操作可从 SQL 中调用中调用中调用中调用 Sybase 扩展了 SQL 表达式的范围以

包括 Java 对象的属性和方法,因此您可以在 SQL 语句中包括 Java 操作。

• Java 类成为域类成为域类成为域类成为域 您用来存储 Java 类的 SQL 语句与传统的 SQL 数据类型使用的 SQL 语句相同。

可以使用 Sun Microsystems Java 开发工具包附带的作为 Java API 的组成

部分的很多类。您还可以使用 Java 开发人员创建和编译的类。

57

Page 72: Adaptive Server Anywhere

关于数据库中的 Java 的问答

Java API 是什么?是什么?是什么?是什么?

Java 应用程序程序员的接口 (API) 是由 Sun Microsystems 创建的一组

类。它提供了一个基本范围的功能, Java 开发人员可以使用和扩展这

些功能。这是您使用 Java 可以执行的任务的核心部分。

Java API 本身也提供了大量功能。 Java API 的很大一部分可用于任何能

够使用 Java 代码的数据库。这说明当前使用 Sun Microsystems Java 开发

工具包 (JDK) 的开发人员应该熟悉 Java API 中的大多数非可视类。

有关受支持的 Java API 的详细信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 "。

如何从如何从如何从如何从 SQL 访问访问访问访问 Java????

除了在类中使用 Java API 外,您还可以在存储过程和 SQL 语句中使用

它。您可以将 Java API 类视为对 SQL 提供的可用内置函数的扩展。

例如, SQL 函数 PI(*) 返回 pi 的值。 Java API 类 java.lang.Math 有一个

名为 PI 的并行字段返回相同的值。但是, java.lang.Math 还有一个名为 E 的字段,该字段返回自然对数的底;并且有一个方法,该方法按照 IEEE 754 标准的规定计算对两个参数的余数运算。

Java API 的其它成员甚至提供了更专门化的功能。例如, java.util.Stack 生成一个后进先出队列,该队列可以存储一个有序列表;java.util.HashTable 将值映射到键; java.util.StringTokenizer 将字符串分

成单个的单词单元。

有关更多信息,请参阅 " 插入、更新和删除 Java 对象 " 第 108 页。

支持哪些支持哪些支持哪些支持哪些 Java 类?类?类?类?

数据库并不支持所有的 Java API 类。某些类,例如包含应用程序的用户

界面组件的 java.awt 包,不适合在数据库服务器内使用。还有其它一

些类 (包括 java.io 的一部分)处理将信息写入磁盘的操作,数据库

服务器环境中也不支持这些类。

58

Page 73: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

有关支持的和不支持的类的详细信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 "和 "ASA SQL 参考手册 > SQL 数据类

型 > 不受支持的 Java 包和类 "。

如何在数据库中使用自己的如何在数据库中使用自己的如何在数据库中使用自己的如何在数据库中使用自己的 Java 类?类?类?类?

可以将您自己的 Java 类安装到数据库中。例如,开发人员可以用 Java 设计、编写并用 Java 编译器编译用户创建的 Employee 类或 Package 类。

用户创建的 Java 类可以同时包含有关主题的信息和某些计算逻辑。安

装在数据库中之后, Adaptive Server Anywhere 可让您在数据库的所有

部分和操作中使用这些类并执行它们的功能 (以类方法或实例方法的形式),就像调用存储过程那样容易。

Java 类和存储过程不同类和存储过程不同类和存储过程不同类和存储过程不同

Java 类不同于存储过程。存储过程是以 SQL 编写的,而 Java 类提供了

功能更强大的语言,并且可以从客户端应用程序中调用,像调用存储过程一样容易,且调用方式也相同。

当 Java 类安装在数据库中之后,它就可以作为一个新域使用。对于任

何您可以使用内置 SQL 数据类型的情况,您都可以使用 Java 类:作为

表中的列类型或作为变量类型。

例如,如果一个名为 Address 的类安装到数据库中,那么表中的一个名

为 Addr 的列可以是 Address 类型,这就意味着只有基于 Address 类的

对象才可以保存为该列的行值。

有关更多信息,请参阅 " 将 Java 类安装到数据库中 " 第 100 页。

可以使用可以使用可以使用可以使用 Java 访问数据吗?访问数据吗?访问数据吗?访问数据吗?

JDBC 接口是一个行业标准,是专门为访问数据库系统而设计的。

JDBC 类可以连接到数据库,使用 SQL 语句请求数据,并返回能够在客

户端应用程序中进行处理的结果集。

59

Page 74: Adaptive Server Anywhere

关于数据库中的 Java 的问答

通常情况下,客户端应用程序使用 JDBC 类,而数据库系统供应商提供 JDBC 驱动程序, JDBC 类使用该驱动程序建立连接。

通过 JDBC,即使用 jConnect 或 JDBC/ODBC Bridge,您可以从客户端

应用程序连接到 Adaptive Server Anywhere。 Adaptive Server Anywhere 还提供了一个内部 JDBC 驱动程序,该驱动程序允许安装在数据库中的 Java 类使用 JDBC 类执行 SQL 语句。

有关更多信息,请参阅 " 使用 JDBC 访问数据 " 第 139 页。

是否可以将类从客户端移到服务器?是否可以将类从客户端移到服务器?是否可以将类从客户端移到服务器?是否可以将类从客户端移到服务器?

可以创建能在企业应用程序的不同层次之间移动的 Java 类。同一 Java 类可以集成到客户端应用程序、中间层或者数据库,总之,您可以集成到 合适的位置。

您可以将包含业务逻辑或数据或两者都包含的类移到企业系统的任何层次 (包括服务器),从而为您 恰当地利用资源提供了十足的的灵活性。它还使得企业客户能够以无与伦比的灵活性使用单一编程语言在多层体系结构中开发他们的应用程序。

可以创建分布式应用程序吗?可以创建分布式应用程序吗?可以创建分布式应用程序吗?可以创建分布式应用程序吗?

可以创建让一部分在数据库中运行而另一部分在客户机上运行的应用程序。可以将 Java 对象从服务器传递到客户机,就像传递诸如字符串和

数值之类的 SQL 数据那样。

有关更多信息,请参阅 " 创建分布式应用程序 " 第 170 页。

用数据库中的用数据库中的用数据库中的用数据库中的 Java 不能做什么?不能做什么?不能做什么?不能做什么?

Adaptive Server Anywhere 是 Java 类的运行时环境,而不是 Java 开发环

境。

不能在数据库中执行下列任务:

• 编辑类源文件 (*.java 文件)。

60

Page 75: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

• 编译 Java 类源文件 (*.java 文件)。

• 执行不受支持的 Java API,如小程序和可视类。

• 执行需要执行本机方法的 Java 方法。安装到数据库中的所有用户

类都必须是 100% 的 Java 类。

必须使用 Java 应用程序开发工具编写和编译 Adaptive Server Anywhere 中使用的 Java 类,然后将这些类安装到数据库中供使用、测试和调试。

61

Page 76: Adaptive Server Anywhere

Java 讲座

Java 讲座讲座讲座讲座

本节介绍 Java 的主要概念。阅读本节之后,您应当能够检查 Java 代码

(如简单的类定义或方法的调用),并能理解正在执行什么操作。

Java 示例目录示例目录示例目录示例目录

本手册中用作示例的那些类位于 Java 示例目录中,该目录就是 SQL Anywhere 目录的 Samples\ASA\Java 子目录。

每个 Java 类示例都由两个文件表示:Java 源代码和已编译的类。您可

以随时将 Java 类示例的已编译版本安装到数据库中 (无需修改)。

了解了解了解了解 Java 类类类类

Java 类将数据和功能 (保存信息和执行计算操作的能力)组合在了一

起。理解类的概念的一种方法是将它视为一个实体,即事物的抽象表示。

例如,您可以设计 Invoice 类来模拟纸质发票 (如在商业活动中每天使

用的那种发票)。正如纸质发票包含一定的信息 (行项目明细、付款方、日期,付款金额、付款到期日)一样, Invoice 类的实例也包含这

些信息。类将信息保存在字段中。

除了描述数据外,类还可以进行计算和执行逻辑操作。例如, Invoice 类可以为每个 Invoice 对象的明细表中的项目计算税款,并将它加到小

计中以得出总计,无须用户干预。这样的类还可以确保 Invoice 中拥有

所有重要的信息,甚至还可指出到期未付的款项或部分支付的款项。计算和其它逻辑操作是由类的方法 执行的。

示例示例示例示例 下面的 Java 代码声明了一个名为 Invoice 的类。这个类声明将存储在名

为 Invoice.java 的文件中,然后将用 Java 编译器编译为 Java 类。

62

Page 77: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

编译编译编译编译 Java 类类类类编译 Java 类的源代码将创建与源文件名称相同但扩展名不同的新文件。

编译 Invoice.java 会创建名为 Invoice.class 的文件,该文件可以

在 Java 应用程序中使用,由 Java VM 执行。

用于编译类声明的 Sun JDK 工具是 javac.exe。

public class Invoice {

// So far, this class does nothing and knows nothing}

使用 class 关键字,后面接的是类的名称。有一对左右大括号:在大括

号之间声明的一切内容 (如字段和方法)都变成了类的组成部分。

事实上,在类声明的外面没有任何 Java 代码。甚至连 Java 解释器自动

运行的、用来创建和管理其它对象的 Java 过程 (经常作为应用程序的

开始部分的 main 方法),它本身也位于类声明内。

Java 中的子类中的子类中的子类中的子类

您可以将类定义为其它类的 " 子类子类子类子类 "。如果一个类是另一个类的子类,

则子类可使用其父类的字段和方法:这叫做 " 继承继承继承继承 "。您可以定义其它

只应用于子类的方法和字段,并可重新定义被继承的字段和方法的含义。

Java 是一个单继承语言,意思是说您创建或使用的所有类 终将从一个

类继承。这意味着低层次的类 (类层次结构中较上面的类)必须存在,才可以使用较高层次的类。运行 Java 应用程序所需要的类的基集被称

为 " 运行时运行时运行时运行时 Java 类类类类 " 或 "Java API"。

了解了解了解了解 Java 对象对象对象对象

" 类类类类 " 是定义对象功能的模板,就像发票表格是定义发票应包含什么信

息的模板一样。

63

Page 78: Adaptive Server Anywhere

Java 讲座

类并不包含有关对象的特定信息。相反,您的应用程序基于类 (模板)创建或 " 实例化实例化实例化实例化 " 对象,而对象保存数据或执行计算。实例化的对

象是类的 " 实例实例实例实例 "。例如, Invoice 对象是 Invoice 类的实例。类定义了

对象能够做什么,而对象是类的具体化,使类具有了意义和用途。

在发票示例中,发票表格定义基于该表格的所有发票能实现什么。表格有一种,而基于该表格的发票可以有零个或多个。表格包含定义,而发票封装用途。

Invoice 对象可以被创建,信息可以被存储、检索、编辑、更新等等。

正像一个发票模板可以创建许多发票一样 (每个发票都与其它发票在细节上不同),您可以从一个类生成许多对象。

方法和字段方法和字段方法和字段方法和字段 " 方法方法方法方法 " 是类中执行某种操作的那一部分,它是一个函数,它代表类执

行计算或与其它对象进行交互。方法可以接受参数,并向调用函数返回值。如果不需要返回值,那么方法便可以返回 void。类可以有许多方

法。

" 字段字段字段字段 " 是类中保存信息的那部分。在创建一个 JavaClass 类型的对象

时, JavaClass 中的字段保存该对象所特有的状态。

类构造函数类构造函数类构造函数类构造函数

可以通过调用类构造函数创建对象。 " 构造函数构造函数构造函数构造函数 " 是具有下列属性的方

法:

• 构造函数方法与类具有相同的名称,但没有声明的数据类型。例

如,可以向下面这样声明一个简单的 Product 类的构造函数:

Product () {...constructor code here...}

• 如果类定义中未包括构造函数方法,那么将使用 Java 基对象提供

的缺省方法。

• 您可以为每个类提供多个构造函数,各自有不同数量、不同类型

的参数。在调用构造函数时,将使用参数数量与类型都适当的构造函数。

64

Page 79: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

了解字段了解字段了解字段了解字段

Java 字段有两类:

• 实例字段实例字段实例字段实例字段 每个对象都有自己的实例字段集,在创建对象时也就

创建了这些实例字段。它们保存该实例所特有的信息。例如,Invoice 类中的 lineItem1Description 字段保存特定发票上的一个细

目的说明。您只能通过对象引用访问实例字段。

• 类字段类字段类字段类字段 类字段保存与任何特定实例无关的信息。类字段是在类

刚加载时创建的,不论创建多少个对象,类字段都只此一份。类字段可以通过类名或对象引用来访问。

要声明类中的字段,首先应声明它的类型,然后是它的名称,并在后面跟一个分号。在声明类字段时,可在声明中使用 Java 关键字 static。应

在类的主体内声明字段,而不是在方法内声明;在方法内声明变量会使变量成为方法的一部分,而不是类的一部分。

示例示例示例示例 类 Invoice 的下列声明有四个字段,对应于在发票上的两个行项目中可

能包含的信息。

public class Invoice { // Fields of an invoice contain the invoice data public String lineItem1Description; public int lineItem1Cost; public String lineItem2Description; public int lineItem2Cost;}

了解方法了解方法了解方法了解方法

Java 方法有两类:

• 实例方法实例方法实例方法实例方法 Invoice 类中的 totalSum 方法可以计算税款和将税款相

加,并返回所有成本的总和,但只有在它与 Invoice 对象 (具有

其行项目成本值的对象)一起调用的情况下才有用。计算只对于对象执行,因为对象 (而不是类)包含发票的行项目。

• 类方法类方法类方法类方法 无须先创建对象即可调用类方法 (也称为

" 静态方法静态方法静态方法静态方法 ")。调用类方法时只需要类和方法的名称。

65

Page 80: Adaptive Server Anywhere

Java 讲座

与实例方法相似,类方法也接受参数并返回值。通常,类方法执行与类的总体功能相关的某种实用程序或信息函数。

类方法不能访问实例字段。

要声明方法,应声明其返回类型、其名称以及它带有的任何参数。与类声明一样,方法使用一对左右大括号来标识方法的主体 (在主体中编写代码)。

public class Invoice { // Fields public String lineItem1Description; public double lineItem1Cost; public String lineItem2Description; public double lineItem2Cost; // A method public double totalSum() { double runningsum; runningsum = lineItem1Cost + lineItem2Cost; runningsum = runningsum * 1.15; return runningsum; }}

在 totalSum 方法的主体内声明了一个名为 runningsum 的变量。首先,

该变量保存第一和第二行项目成本的小计。然后,此小计乘以 15%(税率)以确定总和。

然后,局部变量 (在方法主体内这样称呼)返回给调用函数。当您调用 totalSum 方法时,它返回两个行项目费用字段加上这两个项目的税

费所得的总和。

示例示例示例示例 Adaptive Server Anywhere 所附带的 java.lang.Integer 类的 parseInt 方法

就是一个类方法的示例。当给定一个字符串参数时, parseInt 方法返回

字符串的整数版本。

例如,给定字符串值 "1",无需首先创建 java.lang.Integer 类的实例,

parseInt 方法即可返回 1 (整数值),如下面 Java 代码片段所示:

String num = "1";int i = java.lang.Integer.parseInt( num );

示例示例示例示例 下面的 Invoice 类的版本既包括实例方法又包括类方法。名为 rateOfTaxation 的类方法返回类在计算发票的总和时所使用的税率。

66

Page 81: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

使 rateOfTaxation 方法成为类方法 (而不是实例方法或字段)的优点

是:其它的类和过程可以使用此方法返回的值,而不必先创建类的实例。要返回此类使用的税率,只需要类和方法的名称。

使 rateofTaxation 成为方法而不是成为字段,可使应用程序开发人员更

改计算税率的方式,而不会对使用其返回值的任何对象、应用程序或过程产生不利影响。 Invoice 的未来版本可以基于更复杂的计算求出 rateOfTaxation 类方法的返回值,而不会影响使用其返回值的其它方

法。

public class Invoice { // Fields public String lineItem1Description; public double lineItem1Cost; public String lineItem2Description; public double lineItem2Cost; // An instance method public double totalSum() { double runningsum; double taxfactor = 1 + Invoice.rateOfTaxation(); runningsum = lineItem1Cost + lineItem2Cost; runningsum = runningsum * taxfactor; return runningsum; } // A class method public static double rateOfTaxation() { double rate; rate = .15; return rate; }}

面向对象的语言和过程语言面向对象的语言和过程语言面向对象的语言和过程语言面向对象的语言和过程语言

如果您对过程语言 (如 C)或 SQL 存储过程语言比对面向对象的语言

更熟悉,可通过本节来了解过程语言和面向对象的语言之间的一些主要的相同点和不同点。

Java 基于类基于类基于类基于类 Java 代码的主要结构单元是 " 类类类类 "。

Java 类可以看作是由一些过程和变量组成的集合蜒因为它们都与一个特

定的、可识别的范畴相关,所以将它们归拢在一起。

67

Page 82: Adaptive Server Anywhere

Java 讲座

然而,类的使用方式使得面向对象的语言与过程语言区别开来。当执行以过程语言编写的应用程序时,它通常装载到内存中一次,并让用户沿着预先定义的执行过程执行。

在诸如 Java 之类的面向对象的语言中,类的使用方式与模板相同:定

义潜在的程序执行过程。可以按需要动态创建和加载类的多个副本,并且类的每个实例可以包含它自己的数据、值和执行过程。可以对每个装载的类独立进行操作或者让该类独立执行,这与内存中装载的任何其它类无关。

如果一个类已经装载到内存中准备执行,我们就说该类已被实例化。经过实例化的类叫做对象:它是从类派生出来的应用程序,准备保存唯一值或让其方法独立于其它类实例而执行。

Java 术语术语术语术语

下列条目描述有关 Java 类的某些细节。这一部分并未详细讲述 Java 语言,但可能对您在 Adaptive Server Anywhere 中使用 Java 类有所帮助。

有关 Java 语言的更多信息,请参阅联机手册 《Java 编程思想》(Bruce Eckel 著),该手册包括在 Adaptive Server Anywhere 中,即文件 Samples\ASA\Java\Tjava.pdf。

包包包包 " 包包包包 " 是具有共同用途或属于同一范畴的一组类。包的一个成员具有特

权,可访问该包中其它成员中的数据和方法,即由访问修饰符 protected 修饰的数据和方法。

包就是 Java 中的库。它是可以通过使用 import 语句来提供的类的集

合。以下 Java 语句从 Java API 导入实用程序库:

import java.util.*

包通常包含在 JAR 文件中,该文件的扩展名为 .jar 或 .zip。

公用与专用公用与专用公用与专用公用与专用 访问修饰符可确定一个字段、方法或类是否对其它 Java 对象可见 (可

见性实质上就是任何声明前面使用的 public、 private 或 protected 关键

字)。

• public 类、方法或字段在任何地方均可看到。

• private 类、方法或字段仅在该类中定义的方法中能看到。

68

Page 83: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

• protected 方法或字段对该类中、该类的子类中或同一包中其它类

中定义的方法可见。

• 缺省可见性 (在包中)意味着方法或字段在类中可见并对同一包

中的其它类可见。

构造函数构造函数构造函数构造函数 构造函数是在创建类的实例时调用的 Java 类的特殊方法。

类可以定义它们自己的构造函数,包括多个重载构造函数。在尝试创建对象时使用哪些参数决定使用哪个构造函数。在创建类的实例时,如果使用的参数的类型、数量以及顺序与该类的一个构造函数匹配,则在创建该对象时将使用该构造函数。

垃圾回收垃圾回收垃圾回收垃圾回收 " 垃圾回收垃圾回收垃圾回收垃圾回收 " 自动删除任何未被引用的对象,但在表中作为值存储的对

象例外。

Java 中没有析构函数方法 (C++ 中有)。 Java 类可以定义它们自己的 finalize 方法,用来在垃圾回收期间放弃对象时执行清理操作。

接口接口接口接口 Java 类只能从一个类继承。 Java 使用接口代替多继承。一个类可以实

现多个接口。这些 " 接口接口接口接口 " 各定义一组方法和方法配置文件;要编译

类,类必须实现这些方法和方法配置文件。

接口定义了类必须声明的方法和静态字段。在接口中声明的方法和字段的实现位于使用该接口的类内:接口定义类必须声明什么;如何实现则由类决定。

Java 错误处理错误处理错误处理错误处理

Java 错误处理代码与用于普通处理的代码是分开的。

错误会生成表示错误的例外对象,这叫做 " 抛出例外抛出例外抛出例外抛出例外 "。如果未能在应

用程序的某个层次捕获并适当处理抛出的例外,则将终止 Java 程序。

无论是 Java API 类还是自定义创建的类都有可能抛出例外。事实上,用

户可以创建自己的例外类,这些类会引发他们自己自定义创建的类。

如果发生例外的方法的主体内没有例外处理程序,对例外处理程序的搜索就会继续沿调用堆栈向回搜索。如果到达调用堆栈的顶部仍未找到例外处理程序,那么就会调用运行该应用程序的 Java 解释器的缺省例外

处理程序,同时应用程序会终止。

69

Page 84: Adaptive Server Anywhere

Java 讲座

在 Adaptive Server Anywhere 中,如果 SQL 语句调用 Java 方法,并抛出

了未处理的例外,那么就会生成一个 SQL 错误。

Java 中的错误类型中的错误类型中的错误类型中的错误类型 Java 中的所有错误都出自两种错误类:Exception 和 Error。通常,基于 Exception 的错误由方法主体中的错误处理代码来处理。 Error 类型的错

误专门表示 Java 运行时系统内的内部错误和资源耗尽错误。

Exception 类错误抛出后会被捕获。例外处理代码的以 try、 catch 和 finally 的代码块为特征。

try 块执行有可能生成错误的代码。 catch 块是在 try 块的执行生成 (或

抛出)错误的情况下执行的代码。

finally 块定义这样一个代码块:无论是否生成和捕获错误都将执行,通

常用于清理操作。它用于表示那些在任何情况下都不能省略的代码。

有两种例外类错误:运行时例外错误以及非运行时例外错误。

运行时系统生成的错误也称作隐式例外,因为它们不必作为每个类或方法声明的组成部分来显式处理。

例如,任何时候使用数组都有可能发生数组超出界限这种例外,但该错误不一定是使用数组的类或方法的声明的组成部分。

所有其它例外都是显式的。如果被调用的方法会抛出错误,那么它必须由使用例外抛出方法的类显式捕获,或者该类必须通过在其类声明中标识可能生成的例外来显式抛出错误。显式例外自然必须以显式方式处理。方法必须声明它引发的所有显式错误,或者捕获所有可能被引发的显式错误。

在编译时会检查非运行时例外。非运行时例外通常是由编程中的错误引起的。在运行代码之前, Java 会在编译期间捕获许多这样的错误。

给每个 Java 方法都提供了备用执行路径,使所有的 Java 方法都能完

成,即使它们无法正常完成。如果没有捕获所抛出错误的类型,则该错误会被传递给堆栈中的下一个代码块或方法。

70

Page 85: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

数据库中的数据库中的数据库中的数据库中的 Java 的运行时环境的运行时环境的运行时环境的运行时环境

本节介绍 Sybase 的 Java 运行时环境,并介绍它与标准的 Java 运行时环

境有何不同。

支持的支持的支持的支持的 Java 和和和和 JDBC 版本版本版本版本

Sybase Java VM 可让您选择使用 JDK 1.1、 JDK 1.2 或 JDK 1.3 编程接

口。提供的具体版本是 JDK 版本 1.1.8 和 1.3。

在 JDK 的 1.0 版本和 1.1 版本之间,推出了多个新的 API。同样,有几

种 API 已被放弃:推荐不再使用某些 API,在将来的版本中可能不再支

持它们。

使用被放弃的 API 的 Java 类文件在编译时会生成警告,但在遵循版本 1.1 标准的 Java 虚拟机 (如 Sybase VM)上仍能执行。

内部 JDBC 驱动程序支持 JDBC 版本 2。

有关支持的 JDK API 的更多信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 "。

有关如何创建支持 Java 的数据库的信息,请参阅 " 为数据库启用 Java" 第 94 页。

运行时运行时运行时运行时 Java 类类类类

运行时 Java 类是低层类,它们在创建数据库或为数据库启用 Java 时会

提供给数据库。这些类包括 Java API 的子集,它们是 Sun Java 开发工具

包的组成部分。

运行时类提供了建立应用程序所依据的基本功能。数据库中的类始终可以使用这些运行时类。

可以将运行时 Java 类合并到用户自己创建的类中:或者继承它们的功

能,或者在一个方法中的计算或操作内使用它们。

示例示例示例示例 运行时 Java 类中包括的一些 Java API 类有:

71

Page 86: Adaptive Server Anywhere

数据库中的 Java 的运行时环境

• 基元基元基元基元 Java 数据类型数据类型数据类型数据类型 Java 中的所有基元 (本机)数据类型都有对

应的类。除了能够创建这些类型的对象外,这些类还有其它有用的功能。

Java int 数据类型在 java.lang.Integer 中有对应的类。

• 实用程序包实用程序包实用程序包实用程序包 包 java.util.* 包含许多非常有用的类,这些类的功能

在 Adaptive Server Anywhere 中提供的 SQL 函数中没有对等的功

能。

现将这些类中的一部分列举如下:

• Hashtable 将键映射到值。

• StringTokenizer 将字符串分成相互分开的单词。

• Vector 保存大小可动态变化的对象数组。

• Stack 保存后进先出的对象堆栈。

• SQL 操作的操作的操作的操作的 JDBC 包 java.SQL.* 包含了 Java 对象使用 SQL 语句

从数据库中提取数据时所需要的类。

与用户定义的类不同,运行时类未存储在数据库中,而存储在 Adaptive Server Anywhere 安装目录的 java 子目录下的文件中。

用户定义的类用户定义的类用户定义的类用户定义的类

用户定义的类使用 INSTALL 语句安装在数据库中。安装之后,数据库

中的其它类便可以使用它们。如果它们是公共类,则它们还作为域通过 SQL 提供。

有关安装类的更多信息,请参阅 " 将 Java 类安装到数据库中 " 第 100页。

标识标识标识标识 Java 方法和字段方法和字段方法和字段方法和字段

SQL 中的点中的点中的点中的点 在 SQL 语句中,点标识表的列,如下面的查询:

SELECT employee.emp_idFROM employee

72

Page 87: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

点也可在限定的对象名中指示对象所有权:

SELECT emp_idFROM DBA.employee

Java 中的点中的点中的点中的点 在 Java 中,点是为 Java 类或对象的字段调用方法或访问字段的 " 运算运算运算运算

符符符符 "。它也可以是标识符的一部分,用于标识类名,例如在完全限定类

名 java.util.Hashtable 中。

在下面的 Java 代码片段中,点在代码第一行中是标识符的组成部分。

在代码的第二行中,它是一个运算符。

java.util.Random rnd = new java.util.Random();int i = rnd.nextInt();

从从从从 SQL 调用调用调用调用 Java 方方方方法法法法

在 SQL 中,点运算符可以替换为双右尖括号 (>>)。点运算符更像是 Java 运算符,但会在现有 SQL 名称方面造成多义现象。使用 >> 可避免

这种多义性。

SQL 中的中的中的中的 >> 与与与与 Java 中的中的中的中的 >> 不同不同不同不同

在 SQL 语句中,只有在下面这种情况下才使用双右尖括号运算符:如

果不使用双右尖括号运算符,则将使用 Java 点运算符。在 Java 类内,

双右尖括号不能用来替换点操作符;双右尖括号作为右位移运算符,具有与点运算符完全不同的含义。

例如,下面的批处理 SQL 语句是有效的:

CREATE VARIABLE rnd java.util.Random;SET rnd = NEW java.util.Random();SELECT rnd>>nextInt();

SELECT 语句的结果是随机生成的整数。

下面的 SQL 语句使用上面的 SQL 代码示例创建的变量,说明类方法的

正确用法:

SELECT java.lang.Math>>abs( rnd>>nextInt() );

73

Page 88: Adaptive Server Anywhere

数据库中的 Java 的运行时环境

Java 区分大小写区分大小写区分大小写区分大小写

Java 语法会像您预期的那样工作,而 SQL 语法不会因 Java 类的存在而

发生改变。即使同一 SQL 语句同时包含 Java 和 SQL 语法,情况也是如

此。这句话虽然简单,但其含义却很深远。

Java 是区分大小写的。 Java 类 FindOut 与类 Findout 是两个完全不同的

类。 SQL 在关键字和标识符方面不区分大小写。

即使将 Java 嵌入到不区分大小写的 SQL 语句中时, Java 也保留区分大

小写的特点。这些语句的 Java 部分必须区分大小写,尽管 Java 语法前

面的部分和后面的部分大写小写都可以。

例如,下面的 SQL 语句能够成功地执行,因为 Java 对象、类和运算符

的大小写都注意到了,尽管该语句中其余的 SQL 部分的大小写有所变

化。

SeLeCt java.lang.Math.random();

数据类型数据类型数据类型数据类型 当您使用 Java 类作为列的数据类型时,它是用户定义的 SQL 数据类

型。但是,它仍要区分大小写。此约定可避免只在大小写方面不同的 Java 类含义不明确。

Java 和和和和 SQL 中的字符串中的字符串中的字符串中的字符串

一对双引号在 Java 中标识字符串常值,如下面的 Java 代码片段所示:

String str = "This is a string";

但是,在 SQL 中,单引号标识字符串,而双引号表示标识符,如下面

的 SQL 语句所示:

INSERT INTO TABLE DBA.t1VALUES( 'Hello' )

在 Java 源代码中应总是使用双引号,而在 SQL 语句中则应使用单引

号。

例如,下面的 SQL 语句是有效的。

74

Page 89: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

CREATE VARIABLE str char(20);SET str = NEW java.lang.String( 'Brand new object' )

下面的 Java 代码片段在 Java 类内使用时也是有效的。

String str = new java.lang.String( "Brand new object" );

打印到命令行打印到命令行打印到命令行打印到命令行

打印到标准输出是检查代码执行中的各个点的变量值和执行结果的快速方式。在遇到下面的 Java 代码片段的第二行中的方法时,它接受的字

符串参数将打印到标准输出。

String str = "Hello world";System.out.println( str );

在 Adaptive Server Anywhere 中,标准输出是服务器窗口,因此字符串

会在此显示。在数据库内执行上面的 Java 代码相当于执行下面的 SQL 语句。

MESSAGE 'Hello world'

使用使用使用使用 main 方法方法方法方法

当类包含与以下声明匹配的 main 方法时,大多数 Java 运行时环境(如 Sun Java 解释器)会自动执行它。通常情况下,这种静态方法只有在它

是被 Java 解释器激活的类时才执行。

public static void main( String args[ ] ) { }

由于此方法对测试 Java 对象的功能很有用,所以在 Sun Java 运行时系

统启动时,总会确保首先调用这种方法。

在 Adaptive Server Anywhere 中, Java 运行时系统始终是可用的。可以

使用 SQL 语句以一种即席动态方式测试对象和方法的功能。在许多方

面,这种测试 Java 类功能的方法要灵活得多。

75

Page 90: Adaptive Server Anywhere

数据库中的 Java 的运行时环境

范围和持久性范围和持久性范围和持久性范围和持久性

SQL 变量只在连接期间是持续的。这与 Adaptive Server Anywhere 的早

期版本相比没有发生变化,也不受变量是 Java 类还是本机 SQL 数据类

型的影响。

Java 类的持久性与数据库中的表类似:表在数据库中一直存在,直至您

删除它们,无论它们是否包含数据甚至也无论它们是否被使用过。安装到数据库中的 Java 类是相似的:除非您用 REMOVE 语句显式删除它

们,否则它们一直是可用的。

有关删除类的详细信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > REMOVE 语句 "。

安装的 Java 类中的类方法可以在任何时候从 SQL 语句调用。您可以在

任何能够执行 SQL 语句的位置执行下面的语句。

SELECT java.lang.Math.abs(-342)

Java 对象只有两种形式:作为变量的值或作为表中的值。

SQL 语句中的语句中的语句中的语句中的 Java 转义字符转义字符转义字符转义字符

在 Java 代码中,您可以使用转义字符在字符串中插入某些特殊字符。

请看下面的代码,该代码在包含撇号的句子前面插入一个新行和制表符。

String str = "\n\t\This is an object\'s string literal";

只有在将 Java 转义字符用作 Java 类时, Adaptive Server Anywhere 才允

许使用 Java 转义字符。但是,在 SQL 内,您必须遵循适用于 SQL 中的

字符串的规则。

例如,要给使用 SQL 语句的字段传递字符串值,您可以使用下面的语

句,但 Java 转义字符就不行。

SET obj.str = '\nThis is the object''s string field';

有关 SQL 字符串处理规则的更多信息,请参阅 "ASA SQL 参考手册 > SQL 语言元素 > 字符串 "。

76

Page 91: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

关键字冲突关键字冲突关键字冲突关键字冲突

SQL 关键字可能会与 Java 类 (包括 API 类)的名称冲突。在引用 java.util.* 包成员的类 (例如 Date 类)的名称时,就会发生这种情况。

SQL 保留了单词 Date,将它用作关键字,尽管它又是 Java 类的名称。

当出现这种多义性时,您可以使用双引号标识您没有将该单词用作 SQL 保留字。例如,下面的 SQL 语句会造成错误,因为 Date 是 SQL 的保留

关键字。

-- This statement is incorrectCREATE VARIABLE dt java.util.Date

然而,下面的两个语句都是正确的,因为单词 Date 在引号内。

CREATE VARIABLE dt java.util."Date";

SET dt = NEW java.util."Date"(1997, 11, 22, 16, 11,01)

变量 dt 在这里包含下面的时间:1997 年 11 月 22 日下午 4:11。

import 语句的使用语句的使用语句的使用语句的使用

在 Java 类声明中包括一个 import 语句以访问另一个包中的类,这种情

况很常见。您可以使用非限定类名引用导入的类。

例如,您可以采用两种方式引用 java.util 包的 Stack 类:

• 显式使用名称 java.util.Stack,或

• 使用名称 Stack,并包括下面的 import 语句:

import java.util.*;

还必须安装层次结构还必须安装层次结构还必须安装层次结构还必须安装层次结构中的更高层的类中的更高层的类中的更高层的类中的更高层的类

由另一个类引用的类,无论是用完全限定名称显式引用的还是使用 import 语句隐式引用的,也都必须安装在数据库中。

77

Page 92: Adaptive Server Anywhere

数据库中的 Java 的运行时环境

import 语句在已编译的类内如预期的那样工作。然而,在 Adaptive Server Anywhere 运行时环境内,不存在与 import 语句相当的语句。

SQL 语句或存储过程中使用的所有类名都必须是完全限定的。例如,要

创建 String 类型的变量,您应使用完全限定的名称

(java.lang.String)来引用类。

使用使用使用使用 CLASSPATH 变量变量变量变量

Sun 的 Java 运行时环境和 Sun JDK Java 编译器使用了 CLASSPATH 环境

变量来定位 Java 代码内引用的类。 CLASSPATH 变量提供了 Java 代码

和实际文件路径或引用的类的 URL 位置之间的链接。例如, import

java.io.* 允许在不使用完全限定名称的情况下引用 java.io 包中的所有

类。在下面的 Java 代码中只需要类名即可使用 java.io 包中的类。将要

编译 Java 类声明所在的系统上的 CLASSPATH 环境变量必须包括 Java 目录 (java.io 包的根)的位置。

CLASSPATH 在运在运在运在运

行时被忽略行时被忽略行时被忽略行时被忽略

CLASSPATH 环境变量在执行 Java 操作期间不影响 Java 的 Adaptive Server Anywhere 运行时环境,因为类存储在数据库中,而不是存储在

外部文件或档案中。

用于安装类的用于安装类的用于安装类的用于安装类的 CLASSPATH

然而, CLASSPATH 变量可以在安装类期间用于定位文件。例如,下面

的语句将用户创建的 Java 类安装到数据库中,但只指定文件的名称,

而不指定其完整的路径和名称。(请注意,此语句不涉及 Java 操作。)

INSTALL JAVA NEWFROM FILE 'Invoice.class'

如果指定的文件位于 CLASSPATH 环境变量指定的目录或 zip 文件中,

那么 Adaptive Server Anywhere 将成功地定位该文件并安装类。

公共字段公共字段公共字段公共字段

在面向对象的编程中,将类字段定义为 private,且只通过 public 方法提

供它们的值,这是一种常见做法。

本文档中使用的许多示例都使字段成为公共字段,以使示例更紧凑,更方便阅读。与访问公共方法相比,使用 Adaptive Server Anywhere 中的

公共字段还提高了性能。

78

Page 93: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

本文档中遵循的一般约定是:用户创建的用于 Adaptive Server Anywhere 的 Java 类在其字段中公开其主要值,并在方法中包含可以在这些字段

上执行的自动计算和逻辑。

79

Page 94: Adaptive Server Anywhere

教程:数据库中的 Java 练习

教程:数据库中的教程:数据库中的教程:数据库中的教程:数据库中的 Java 练习练习练习练习

本教程是关于使用 SQL 语句在 Java 类和对象上调用 Java 操作的初级读

物。其中介绍如何将 Java 类安装到数据库中,还介绍如何从 SQL 语句

中访问类以及其成员和方法。本教程使用了 ""Java 讲座 " 第 62 页 " 中创

建的 Invoice 类。

要求要求要求要求 本教程假定您在数据库软件中安装了 Java,并假定您已经安装了 Java 开发工具包 (JDK),包括 Java 编译器 (javac)。

资源资源资源资源 本示例的源代码和批处理文件位于您的 SQL Anywhere 目录下的目录 Samples\ASA\JavaInvoice 中。

创建和编译示例创建和编译示例创建和编译示例创建和编译示例 Java 类类类类

第一步是编写 Java 代码并对其进行编译。此项工作应在数据库外进行。

❖ 创建和编译类:创建和编译类:创建和编译类:创建和编译类:

1 创建一个名为 Invoice.java 的文件,该文件包含以下代码。

public class Invoice { // Fields public String lineItem1Description; public double lineItem1Cost; public String lineItem2Description; public double lineItem2Cost; // An instance method public double totalSum() { double runningsum; double taxfactor = 1 + Invoice.rateOfTaxation(); runningsum = lineItem1Cost + lineItem2Cost; runningsum = runningsum * taxfactor; return runningsum; } // A class method public static double rateOfTaxation() {

80

Page 95: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

double rate; rate = .15; return rate; }}

您可以在 SQL Anywhere 目录下的文件 Samples\ASA\JavaInvoice\Invoice.java 中找到该类的源

代码。

2 编译该文件以创建文件 Invoice.class。

从 Invoice.java 所在的目录中的命令提示符下,执行下面的

命令。

javac *.java

该类现在已被编译并可以安装到数据库中。

安装示例安装示例安装示例安装示例 Java 类类类类

必须将 Java 类安装到数据库中,然后才能使用它们。可以从 Sybase Central 或 Interactive SQL 安装类。本节对这两种情况都提供了说明,您

可以选择自己比较喜欢的一种方法。

❖ 将类安装到示例数据库将类安装到示例数据库将类安装到示例数据库将类安装到示例数据库 ( Sybase Central )::::

1 启动 Sybase Central 并连接到示例数据库:

2 打开 "Java 对象 " 文件夹并双击 " 添加 Java 类 "。 " 创建 Java 类" 向导将出现。

3 使用 " 浏览 " 按钮定位到 SQL Anywhere 目录的 Samples\ASA\JavaInvoice 子目录中的 Invoice.class。

4 单击 " 完成 " 退出该向导。

81

Page 96: Adaptive Server Anywhere

教程:数据库中的 Java 练习

❖ 将类安装到示例数据库将类安装到示例数据库将类安装到示例数据库将类安装到示例数据库 ( Interactive SQL )::::

1 启动 Interactive SQL 并连接到示例数据库。

2 在 Interactive SQL 的 "SQL 语句 " 窗格中,键入以下命令:

INSTALL JAVA NEWFROM FILE'path\\samples\\ASA\\JavaInvoice\\Invoice.class'

其中 path 是 SQL Anywhere 目录。

类现在已安装到示例数据库中。

注意注意注意注意 • 此时还没有发生任何数据库中的 Java 操作。类已经安装到数据库

中,可随时用作表中的变量或列的数据类型。

• 从此以后对类文件所做的更改将不会 自动反映到数据库中的类的

副本中。如果您希望这些更改得到反映,则必须重新安装类。

有关安装类的更多信息,以及有关更新已安装的类的信息,请参阅 " 将 Java 类安装到数据库中 " 第 100 页。

创建创建创建创建 Invoice 类型的类型的类型的类型的 SQL 变量变量变量变量

本节创建了一个 SQL 变量,该变量引用一个 Invoice 类型的 Java 对象。

区分大小写区分大小写区分大小写区分大小写Java 是区分大小写的,因此本节下面的示例中的属于 Java 语法的部分

是使用正确的大小写编写的。 SQL 语法以大写形式表示。

1. 从 Interactive SQL 中,执行下面的语句以创建一个 Invoice 类型的名

为 Inv 的 SQL 变量,其中 Invoice 是您安装到数据库中的 Java 类:

CREATE VARIABLE Inv Invoice

创建变量之后,只有在其数据类型和声明的数据类型完全相同或者指派的值是声明的数据类型的子类时,才为该变量赋值。在此例中,变量 Inv 只能包含对 Invoice 类型的对象或 Invoice 的子类的引

用。

82

Page 97: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

初,变量 Inv 是 NULL,因为没有值传递给它。

2. 执行下面的语句以标识变量 Inv 的当前值。

SELECT IFNULL(Inv, 'No object referenced', 'Variable not null: contains object reference')

该变量当前没有引用任何对象。

3. 为 Inv 赋值。

必须使用 NEW 关键字实例化 Invoice 类的一个实例。

SET Inv = NEW Invoice()

现在, Inv 变量具有对 Java 对象的引用。要验证这一点,您可以执

行步骤 2 的语句。

Inv 变量包含对 Invoice 类型的 Java 对象的引用。使用该引用,您可

以访问对象的任何字段或调用其任何方法。

访问访问访问访问 Java 对象的字段和方法对象的字段和方法对象的字段和方法对象的字段和方法

如果变量 (或表中的列值)包含对 Java 对象的引用,则可以给该对象

的字段传递值并可以调用其方法。

例如,您在上一节中创建的 Invoice 类型的变量包含对 Invoice 对象的引

用,并有四个字段,这四个字段的值可以使用 SQL 语句来设置。

❖ 访问访问访问访问 Invoice 对象的字段:对象的字段:对象的字段:对象的字段:

1 从 Interactive SQL 中,执行下面的 SQL 语句来为变量 Inv 设置

字段值。

SET Inv.lineItem1Description = 'Work boots';SET Inv.lineItem1Cost = '79.99';SET Inv.lineItem2Description = 'Hay fork';SET Inv.lineItem2Cost = '37.49';

每个 SQL 语句都给 Inv 引用的 Java 对象中的字段传递一个值。

83

Page 98: Adaptive Server Anywhere

教程:数据库中的 Java 练习

2 针对该变量执行 SELECT 语句。下面任一 SQL 语句都返回 Inv 引用的 Java 对象中一个字段的当前值。

SELECT Inv.lineItem1Description;SELECT Inv.lineItem1Cost;SELECT Inv.lineItem2Description;SELECT Inv.lineItem2Cost;

3 在 SQL 表达式中使用 Inv 变量的字段。

执行上面的 SQL 语句后, 执行下面的 SQL 语句。

SELECT * FROM PRODUCTWHERE unit_price < Inv.lineItem2Cost;

除了有公共字段外, Invoice 类还有一个实例方法,您可以调用该方法

❖ 调用调用调用调用 Invoice 对象的方法:对象的方法:对象的方法:对象的方法:

• 从 Interactive SQL 中,执行下面的 SQL 语句,该 SQL 语句调用

变量 Inv 引用的对象的 totalSum() 方法。它返回两个费用字段

的总和加上对此总和征收的税款。

SELECT Inv.totalSum();

调用方法与引用字段调用方法与引用字段调用方法与引用字段调用方法与引用字段 方法名称后面总是带有括号,即使它们没有参数也是如此。字段名后面不带括号。

totalSum() 方法没有参数,但是会返回一个值。它使用了括号,因为调

用的是 Java 操作,尽管该方法没有参数。

对于数据库中的 Java,直接的字段访问比方法调用更快。访问字段不需

要调用 Java VM,而调用方法需要 VM 执行所调用的方法。

正如本节开始时介绍的 Invoice 类定义所示, totalSum 实例方法利用了

类方法 rateOfTaxation。

您可以直接从 SQL 语句访问该类方法。

SELECT Invoice.rateOfTaxation();

84

Page 99: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

请注意,这里使用了类的名称,而不是变量 (包含对 Invoice 对象的引

用)的名称。这与 Java 处理类方法的方式一致,尽管它是用在 SQL 语句中。即使没有实例化任何基于该类的对象,也可以调用类方法。

可以在一个对象上调用类方法,尽管类方法调用不要求有一个正常工作的实例。下面的 SQL 语句与前面执行的 SQL 语句产生的结果相同。

SELECT Inv.rateOfTaxation();

在表中保存在表中保存在表中保存在表中保存 Java 对象对象对象对象

当您在数据库中安装类时,它被作为一种新的数据类型来提供。表中的列可以是 Javaclass 类型,这里的 Javaclass 是一种已安装的公共 Java 类的名称。然后,您可以创建一个 Java 对象并将它作为列的值添加到表

中。

❖ 在表中使用在表中使用在表中使用在表中使用 Invoice 类:类:类:类:

1 创建一个表,让该表带有一个 Invoice 类型的列。

从 Interactive SQL,执行下面的 SQL 语句。

CREATE TABLE T1 ( ID int, JCol Invoice);

名为 JCol 的列只接受 Invoice 类型的对象或它的一个子类。

2 使用变量 Inv(该变量包含对一个 Invoice 类型的 Java 对象的引

用),执行下面的 SQL 语句以向表 T1 中添加一行。

INSERT INTO T1

VALUES( 1, Inv );

对象被添加到表 T1 之后,您可以发布涉及该表中对象的字段和

方法的选择语句。

3 执行下面的 SQL 语句,为表 T1 中的所有对象返回字段 lineItem1Description 的值 (现在,该表中应只有一个对象)。

85

Page 100: Adaptive Server Anywhere

教程:数据库中的 Java 练习

SELECT ID, JCol.lineItem1DescriptionFROM T1;

您可以执行类似的涉及该对象的其它字段和方法的选择语句。

4 创建 Java 对象并将它添加到表中的第二个方法,需要用到下面

的表达式,该表达式总是创建 Java 对象并返回一个对它的引

用。

NEW Javaclassname()

5 此表达式的使用方式有多种。例如,执行下面的 SQL 语句以创

建一个 Java 对象并将它插入到表 T1 中。

INSERT INTO T1

VALUES ( 2, NEW Invoice() );

6 执行下面的 SQL 语句以验证这两个对象是否已被保存为表 T1 中的列 JCol 的值。

SELECT ID, JCol.totalSum()FROM t1

JCol 列 (上面的语句返回的第二行)的结果应该为 0,因为该

对象中的字段没有值,而 totalSum 方法是对这些字段的计算。

使用查询返回对象使用查询返回对象使用查询返回对象使用查询返回对象

除了访问字段和方法外,您还可以使用查询从表中检索整个对象。

❖ 访问存储在表中的访问存储在表中的访问存储在表中的访问存储在表中的 Invoice 对象:对象:对象:对象:

• 从 Interactive SQL,执行下面的一系列语句来创建一个新的变

量并传递一个值 (它只能包含一个对象引用,这里的对象是 Invoice 类型的对象)。向变量传递的对象引用是早先使用表 T1 生成的。

CREATE VARIABLE Inv2 Invoice;SET Inv2 = (select JCol from T1 where ID = 2);SET Inv2.lineItem1Description = 'Sweet feed';SET Inv2.lineItem2Description = 'Drive belt';

86

Page 101: Adaptive Server Anywhere

第 3 章 介绍数据库中的 Java

lineItem1Description 字段和 lineItem2Description 的值在变量 Inv2 中已经改变,但是在作为此变量值的源的表中没有改变。

这与当前处理 SQL 变量的方式一致:变量 Inv 包含对一个 Java 对象的引用。表 (该变量的引用的源)中的值直到执行 UPDATE 语句之后才发生了改变。

87

Page 102: Adaptive Server Anywhere

教程:数据库中的 Java 练习

88

Page 103: Adaptive Server Anywhere

第 4 章

在数据库中使用在数据库中使用在数据库中使用在数据库中使用 Java

关于本章关于本章关于本章关于本章 本章介绍如何向数据库中添加 Java 类和对象以及如何在关系数据库中

使用这些对象。

预备知识预备知识预备知识预备知识 要运行本章中的示例,请首先运行 SQL Anywhere 目录下的 Samples\ASA\Java\jdemo.sql 文件。

有关更多信息和完整说明,请参阅 "" 设置 Java 示例 " 第 90 页 "。

89

Page 104: Adaptive Server Anywhere

简介

简介简介简介简介

本章介绍如何通过在数据库中使用 Java 来完成各种任务,其中包括下

列任务:

• 如何为数据库启用如何为数据库启用如何为数据库启用如何为数据库启用 Java 您需要按照几个步骤操作来使您的数据

库能够使用 Java。

• 安装安装安装安装 Java 类类类类 您需要在数据库中安装 Java 类,使这些 Java 类能

够用在服务器中。

• Java 列的属性列的属性列的属性列的属性 本节介绍如何使数据类型为 Java 类的列符合关系

模型。

• Java 数据库设计数据库设计数据库设计数据库设计 本节为设计使用 Java 类的数据库提供一些技

巧。

设置设置设置设置 Java 示例示例示例示例

本章中的许多示例要求您使用一组添加到示例数据库中的类和表。这些表与示例数据库中同名的表保存相同的信息,但是它们归名为 jdba 的用

户 ID 所拥有。它们使用 Java 类数据类型 (而非简单的关系类型)来保

存信息。您可以在 SQL Anywhere 目录的 Samples\ASA\Java 子目录中

找到该示例。

专门为培训设计的示例表专门为培训设计的示例表专门为培训设计的示例表专门为培训设计的示例表示例表阐释了不同的 Java 功能。它们不是针对如何重新设计数据库提

出的建议。在评估应在什么位置加入 Java 数据类型和其它功能时,应

考虑您自己的具体情况。

设置 Java 示例包括两个步骤:

1. 为示例数据库启用 Java。

2. 添加 Java 示例类和表。

90

Page 105: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

❖ 为示例数据库启用为示例数据库启用为示例数据库启用为示例数据库启用 Java::::

1 启动 Interactive SQL 并连接到示例数据库。

2 在 Interactive SQL 的 "SQL 语句 " 窗格中,键入以下语句:

ALTER DATABASE UPGRADE JAVA JDK '1.3'

3 关闭 Interactive SQL 和示例数据库。

必须关闭 asademo.db 数据库才能使用 Java 功能。

❖ 向示例数据库中添加向示例数据库中添加向示例数据库中添加向示例数据库中添加 Java 类和表:类和表:类和表:类和表:

1 启动 Interactive SQL 并连接到示例数据库。

2 在 Interactive SQL 的 "SQL 语句 " 窗格中,键入以下语句:

READ "path\\Samples\\ASA\\Java\\jdemo.sql"

其中 path 是 SQL Anywhere 目录。这样就会运行 jdemo.sql 命令文件中的指令。完成这些指令需要一些时间。

您可以使用文本编辑器来查看脚本 Samples\ASA\Java\jdemo.sql。它执行下列步骤:

1. 安装 JDBCExamples 类。

2. 创建一个具有 DBA 权限的用户 ID:用户名为 JDBA,口令为 SQL

;并将当前用户设置为 JDBA。

3. 安装名为 asademo.jar 的 JAR 文件。该文件包含示例表中使用的

那些类定义。

4. 在 JDBA 用户 ID 下创建下列表:

• product

• contact

• customer

91

Page 106: Adaptive Server Anywhere

简介

• employee

• sales_order

• sales_order_items

这是示例数据库中的表的一个子集。

5. 将同名的标准表中的数据添加到 Java 表中。该步骤使用了 SELECT 语句中的 INSERT。执行该步骤可能需要一些时间。

6. 创建一些索引和外键以便向模式中添加完整性约束。

管理管理管理管理 Java 的运行时环境的运行时环境的运行时环境的运行时环境

Java 的运行时环境由以下两部分组成:

• Sybase Java 虚拟机虚拟机虚拟机虚拟机 在数据库服务器内运行, "Sybase Java 虚拟

机 " 解释并执行编译的 Java 类文件。

• Java 运行时类运行时类运行时类运行时类 当您创建数据库时,将有一组 Java 类供数据库使

用。数据库中的 Java 应用程序需要这些运行时类才能正常运行。

Java 的管理任务的管理任务的管理任务的管理任务 如果要为 Java 提供运行时环境,您需要执行下列任务:

• 为数据库启用为数据库启用为数据库启用为数据库启用 Java 该任务包括:确保可以使用内置类并将数据

库升级到版本 8 标准。

有关更多信息,请参阅 "" 为数据库启用 Java" 第 94 页 "。

92

Page 107: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

• 安装用户所需的其它类安装用户所需的其它类安装用户所需的其它类安装用户所需的其它类 该任务涉及到确保安装运行时类以外的

类并使其保持 新。

有关更多信息,请参阅 "" 将 Java 类安装到数据库中 " 第 100 页 "。

• 配置服务器配置服务器配置服务器配置服务器 您必须相应地配置服务器,以便有必要的内存可供

用来运行 Java 任务。

有关更多信息,请参阅 "" 为 Java 配置内存 " 第 136 页 "。

用于管理用于管理用于管理用于管理 Java 的工的工的工的工

具具具具

您可以从 Sybase Central 或从 Interactive SQL 执行所有这些任务。

93

Page 108: Adaptive Server Anywhere

为数据库启用 Java

为数据库启用为数据库启用为数据库启用为数据库启用 Java

Java 的 Adaptive Server Anywhere 运行时环境要求 Java VM 和 "Sybase Java 运行时类运行时类运行时类运行时类 "。。。。为了使数据库能够使用 Java 运行时类,您需要为数据

库启用 Java。

数据库中的 Java 是单独许可的 SQL Anywhere Studio 组件。

新数据库在缺省情况下不启用新数据库在缺省情况下不启用新数据库在缺省情况下不启用新数据库在缺省情况下不启用 Java在缺省情况下,用 Adaptive Server Anywhere 创建的数据库不启用 Java。

Java 是一种单继承语言,即,您创建或使用的所有类 终都从一个类继

承。这意味着必须存在低层类 (层次结构中靠上的类)才能使用高层类。 Java 运行时类或 Java API 是运行 Java 应用程序所需的一组基类。

何时不为数据库启用何时不为数据库启用何时不为数据库启用何时不为数据库启用 Java

为数据库启用 Java 可向系统表中添加许多条目。这样就会增加数据库

的大小,更重要的是,即使您不使用任何 Java 功能,也需要增加大约 200K 用于运行数据库的内存。

如果您不打算使用 Java,并且您在一个内存有限的环境中运行,您可能

不希望为数据库启用 Java。

Sybase 运行时运行时运行时运行时 Java 类类类类

Sybase Java 运行时类保存在磁盘上,而不是像其它类那样存储在数据库

中。下列文件包含 Sybase 运行时 Java 类,这些文件位于 SQL Anywhere 目录的 Java 子目录中:

• 1.1\classes.zip 该文件 (由 Sun Microsystems 许可使用)包含用

于 JDK 1.1.8 的 Sun Microsystems Java 运行时类的子集。

• 1.3\rt.jar 该文件 (由 Sun Microsystems 许可使用)包含用于 JDK 1.3 的 Sun Microsystems Java 运行时类的子集。

• asajdbc.zip 该文件包含用于 JDK 1.1 的 Sybase 内部 JDBC 驱动程

序类。

94

Page 109: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

• asajrt12.zip 该文件包含用于 JDK 1.2 和 JDK 1.3 的 Sybase 内部 JDBC 驱动程序类。

当您为数据库启用 Java 时,也会用系统 JAR 文件中的一系列可用类来

更新系统表。您可以从 Sybase Central 浏览类的层次结构,但是类本身

不存在于数据库中。

JAR 文件文件文件文件 数据库在下列 JAR 文件中存储运行时类名:

• ASAJRT asajdbc.zip 中的类名保存在此处。

• ASAJDBCDRV jdbcdrv.zip 中的类名保存在此处。

• ASASystem classes.zip 中的类名保存在此处。

安装的包安装的包安装的包安装的包 这些运行时类包括下列包:

• java 此处存储的 java 包中包括由 Sun Microsystems 提供的受支持 Java 运行时类。

有关支持的 Java 运行时类的列表,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 "。

• com.sybase 存储在此处的包提供服务器端 JDBC 支持。

• sun Sun Microsystems 提供存储在此处的包。

• sybase.sql 存储在此处的包是 Sybase 服务器端 JDBC 支持的一部

分。

注意:不要安装另一个版本的注意:不要安装另一个版本的注意:不要安装另一个版本的注意:不要安装另一个版本的 Sun JDK 中的类中的类中的类中的类

Sun JDK 中的类与必须安装到任何旨在执行 Java 操作的数据库中的 Sybase 运行时 Java 类共享名称。

您不能替换 Adaptive Server Anywheer 附带的 classes.zip 文件。如果

使用了这些类的另一个版本,将导致与 Sybase Java 虚拟机的兼容方面

出现问题。

您必须 只 使用本节中概述的方法来为数据库启用 Java。

95

Page 110: Adaptive Server Anywhere

为数据库启用 Java

为数据库启用为数据库启用为数据库启用为数据库启用 Java 的方法的方法的方法的方法

您可以在创建数据库、升级数据库或在以后的单独操作过程中为数据库启用 Java。

创建数据库创建数据库创建数据库创建数据库 您可以使用下列方法来创建启用了 Java 的数据库:

• CREATE DATABASE 语句。

有关语法的详细信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > CREATE DATABASE 语句 "。

• dbinit 实用程序。

有关详细信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用

程序 > 使用 dbinit 实用程序创建数据库 "。

• Sybase Central。

有关详细信息,请参阅 "ASA SQL 用户指南 > 使用数据库对象 > 创建数据库 "。

升级数据库升级数据库升级数据库升级数据库 您可以使用下列方法将数据库升级到启用了 Java 的版本 8 数据库:

• ALTER DATABASE 语句。

有关语法的详细信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > ALTER DATABASE 语句 "。

• dbupgrad.exe 升级实用程序。

有关详细信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用

程序 > 使用 dbupgrad 实用程序升级数据库 "。

• Sybase Central。

有关详细信息,请参阅 "" 为数据库启用 Java" 第 98 页 "。

如果您选择不在数据库中安装 Java,则所有不涉及 Java 操作的数据库

操作仍保留完整的功能并且能正常工作。

96

Page 111: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

新数据库和新数据库和新数据库和新数据库和 Java

缺省情况下, Adaptive Server Anywhere 不会在您每次创建数据库时都

安装 Sybase Java 运行时类。安装这个单独许可的组件是可选的,具体

受您创建数据库时使用的方法的制约。

CREATE DATABASE 选项选项选项选项

CREATE DATABASE SQL 语句有一个名为 JAVA 的选项。要为数据库

启用 Java,可将该选项设置为 ON。要禁用 Java,可将该选项设置为 OFF。该选项在缺省情况下设置为 OFF。

例如,以下语句创建名为 temp.db 的、启用了 Java 的数据库文件:

CREATE DATABASE 'c:\\sybase\\asa8\\temp' JAVA ON

以下语句创建名为 temp2.db 的、不支持 Java 的数据库文件。

CREATE DATABASE 'c:\\sybase\\asa8\\temp2'

数据库初始化实用程数据库初始化实用程数据库初始化实用程数据库初始化实用程序序序序

您可以使用 dbinit.exe 数据库初始化实用程序创建数据库。该实用程

序具有控制是否在新创建的数据库中安装 Java 运行时类的选项。在缺

省情况下,不安装这些类。

使用 Sybase Central 创建数据库时有同样的选项供使用。

升级数据库和升级数据库和升级数据库和升级数据库和 Java

您可以使用 Upgrade 实用程序或 ALTER DATABASE 语句来升级用低版

本软件创建的现有数据库。

数据库升级实用程序数据库升级实用程序数据库升级实用程序数据库升级实用程序 您可以使用 dbupgrad.exe 实用程序将数据库升级到 Adaptive Server Anywhere 版本 8 版标准。使用 -jr Upgrade 实用程序选项可阻止安装 Sybase Java 运行时类。

有关数据库中的 Java 在哪些情况下包括在升级的数据库中的信息,请

参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > 使用 dbupgrad 实用

程序升级数据库 "。

97

Page 112: Adaptive Server Anywhere

为数据库启用 Java

为数据库启用为数据库启用为数据库启用为数据库启用 Java

如果您已创建数据库,或者已将数据库升级到标准数据库,但是没有选择为数据库启用 Java,则可在日后使用 Sybase Central 或 Interactive SQL 添加必需的 Java 类。

❖ 向数据库中添加向数据库中添加向数据库中添加向数据库中添加 Java 运行时类运行时类运行时类运行时类 (Sybase Central)::::

1 从 Sybase Central 以具有 DBA 权限的用户身份连接到数据库。

2 右击数据库并选择 " 升级数据库 "。

3 单击向导简介页中的 " 下一步 "。

4 从列表中选择要升级的数据库。

5 如果需要,可选择创建数据库的备份。单击 " 下一步 "。

6 如果需要,可选择安装 jConnect 元信息支持。单击 " 下一步 "。

7 选择 " 安装 Java 支持 " 选项。您必须选择安装 JDK 的哪一个版

本。缺省类是 JDK 1.3 类。对于 7.x 版的数据库,缺省类是 JDK 1.1.8 类。

8 请按照向导其余部分的说明进行操作。

❖ 向数据库中添加向数据库中添加向数据库中添加向数据库中添加 Java 运行时类运行时类运行时类运行时类 (SQL)::::

1 从 Interactive SQL 以具有 DBA 权限的用户身份连接到数据库。

2 执行以下语句:

ALTER DATABASE UPGRADE JAVA ON

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > ALTER DATABASE 语句 "。

3 重新启动数据库以便使 Java 支持生效。

98

Page 113: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

使用使用使用使用 Sybase Central 为数据库启用为数据库启用为数据库启用为数据库启用 Java

您可以使用 Sybase Central 来通过向导创建数据库。在创建或升级数据

库时,向导提示您选择是否安装 Sybase 运行时 Java 类。在缺省情况

下,该选项为数据库启用 Java。

使用 Sybase Central,您可以通过选择下面的一种做法来创建或升级数

据库:

• 从 Utilities 文件夹创建数据库,或者

• 从 Utilities 文件夹升级数据库,将数据库从低版本软件升级到具有 Java 功能的数据库。

99

Page 114: Adaptive Server Anywhere

将 Java 类安装到数据库中

将将将将 Java 类安装到数据库中类安装到数据库中类安装到数据库中类安装到数据库中

在将 Java 类安装到数据库中之前,必须先编译它。可按照如下形式将 Java 类安装到数据库中:

• 单一类单一类单一类单一类 可从编译过的类文件中将单个类安装到数据库中,类文

件的扩展名通常为 .class。

• JAR 如果一组类在经过压缩或未经压缩的 JAR 文件中,您可以

一次将这组类全部安装上。 JAR 文件的扩展名通常为 .jar 或

.zip。 Adaptive Server Anywhere 支持用 Sun JAR 实用程序创建的

所有 JAR 压缩文件以及其它一些 JAR 压缩模式。

本节介绍如何在编译 Java 类之后安装它们。您必须具有 DBA 权限才能

安装类或 JAR。

创建类创建类创建类创建类

您在创建自己的类时会涉及许多步骤,每一步的具体情况会因您是否使用 Java 开发工具 (如 Sybase PowerJ)而有所不同,但一般都会包括以

下步骤:

❖ 创建类:创建类:创建类:创建类:

1 定义类定义类定义类定义类 编写定义类的 Java 代码。如果您使用的是 Sun Java SDK,则可以使用文本编辑器。如果您使用的是开发工具 (如 Sybase PowerJ),开发工具会提供相应的说明。

只使用支持的类只使用支持的类只使用支持的类只使用支持的类如果您的类使用任何运行时 Java 类,请确保 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 " 中列出的支持的类列表中有这些

运行时 Java 类。

用户类必须是 100% 的 Java 类,不允许使用本地方法。

100

Page 115: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

2 命名和保存类命名和保存类命名和保存类命名和保存类 将类声明 (Java 代码)保存在扩展名为 .java 的文件中。确保文件名与类名相同,并且这两个名称的大小写相同。

例如,名为 Utility 的类应保存在名为 Utility.java 的文件

中。

3 编译您的类编译您的类编译您的类编译您的类 该步骤将包含 Java 代码的类声明转化成一个不同

的包含字节代码的新文件。新文件的名称与 Java 代码文件的名

称相同,但是扩展名为 .class。您可以在 Java 运行时环境中

运行编译的 Java 类,不必考虑编译它时使用的是什么平台或运

行时环境的操作系统是哪种。

Sun JDK 包含一个 Java 编译程序 Javac.exe。

仅限于启用了仅限于启用了仅限于启用了仅限于启用了 Java 的数据库的数据库的数据库的数据库

您可以在数据库中安装任何编译的 Java 类文件。但是,只有在按照

""为数据库启用 Java" 第94页"中描述的方法启用了 Java 时,才能执

行那些使用已安装的类的 Java 操作。

安装类安装类安装类安装类

为使 Java 类在数据库内可用,可从 Sybase Central 将该类 " 安装安装安装安装 " 到数

据库中,也可以从 Interactive SQL 或其它应用程序使用 INSTALL 语句

进行安装。您必须知道希望安装的类的路径和文件名。

您需要 DBA 权限来安装类。

❖ 安装类安装类安装类安装类 (Sybase Central)::::

1 以 DBA 权限连接到数据库。

2 打开该数据库的 Java Objects 文件夹。

3 双击 " 添加 Java 类 "。

4 请按照向导中的说明进行操作。

101

Page 116: Adaptive Server Anywhere

将 Java 类安装到数据库中

❖ 安装类安装类安装类安装类 (SQL)::::

1 以 DBA 权限连接到数据库。

2 执行以下语句:

INSTALL JAVA NEWFROM FILE 'path\\ClassName.class'

其中 path 是类文件所在的目录, ClassName.class 是类文件

的名称。

双反斜线可确保斜线不被视为转义字符。

例如,要安装名为 Utility.class 的文件 (保存在 c:\source 目录中)中的类,请输入以下语句:

INSTALL JAVA NEWFROM FILE 'c:\\source\\Utility.class'

如果您使用相对路径,它必须是相对于数据库服务器的当前工作目录。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > INSTALL 语句 " 和 " 删除 Java 对象、类和 JAR 文件 " 第 113 页。

安装安装安装安装 JAR

一个有用而又常见的做法是,将一组相关的类收集到一个包中并将一个或多个包存储在一个 "JAR 文件文件文件文件 " 中。有关 JAR 文件和包的信息,请参

阅随附的联机手册 《Java 编程思想》或其它有关用 Java 编程的手册。

按照类文件的安装方式安装 JAR 文件。 JAR 文件的扩展名可以为 JAR 或 ZIP。每个 JAR 文件在数据库中必须有一个名称。通常,您使用 JAR 文件的名称,但不带扩展名。例如,如果您安装名为 myjar.zip 的 JAR 文件,则通常将赋予它 myjar 这一 JAR 名。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > INSTALL 语句 " 和 " 删除 Java 对象、类和 JAR 文件 " 第 113 页。

102

Page 117: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

❖ 安装安装安装安装 JAR (Sybase Central)::::

1 以 DBA 权限连接到数据库。

2 打开该数据库的 Java Objects 文件夹。

3 双击 " 添加 JAR 文件 "。

4 请按照向导中的说明进行操作。

❖ 安装安装安装安装 JAR (SQL)::::

1 以 DBA 权限连接到数据库。

2 输入以下语句:

INSTALL JAVA NEWJAR 'jarname'FROM FILE 'path\\JarName.jar'

更新类和更新类和更新类和更新类和 Jar

您可以使用 Sybase Central 或通过在 Interactive SQL 中输入 INSTALL 语句或通过某个其它客户端应用程序来更新类和 JAR 文件。

要更新类或 JAR,您必须具有 DBA 权限,并且磁盘上的某个文件中要

有较新版本的已编译的类文件或 JAR 文件。

现有的现有的现有的现有的 Java 对象和对象和对象和对象和

升级的类升级的类升级的类升级的类

您可以将 Java 类的实例以 Java 对象形式存储在数据库中,或者以值的

形式存储在将该类作为其数据类型的列中。

虽然对类进行了更新,那些已存在的旧值仍然有效,即使表中存储的字段和方法与新的类定义不兼容也无妨。

不过,插入的任何新行需要与新定义兼容。

更新的类何时生效更新的类何时生效更新的类何时生效更新的类何时生效 只有在安装类之后建立的新连接或者在安装类之后首次使用类的新连接,才使用新定义。在 " 虚拟机 " 装载了类定义之后,它就会一直停留

在内存中,直到连接关闭。

103

Page 118: Adaptive Server Anywhere

将 Java 类安装到数据库中

使用基于当前连接中的某个 Java 类或类的对象,那么,要使用新的类

定义,就需要断开连接并重新连接。

若想了解更新后的类为什么这样才能生效,您需要了解一些有关 VM 工作方式的知识。有关信息,请参阅 "" 为 Java 配置内存 " 第 136 页 "。

以序列化形式存储的以序列化形式存储的以序列化形式存储的以序列化形式存储的对象对象对象对象

Java 对象可以使用更新的类定义,因为它们以序列化形式存储。序列化

格式是专门为数据库设计的,它并不是 Sun Microsystems 的序列化格

式。内部的 Sybase VM 会执行所有序列化和反序列化,因此,不存在任

何兼容性问题。

❖ 更新类或更新类或更新类或更新类或 JAR (Sybase Central)::::

1 以 DBA 权限连接到数据库。

2 打开 Java Objects 文件夹。

3 查找希望更新的类或 JAR 文件。

4 右击该类或 JAR 文件并从弹出式菜单选择 " 更新 "。

5 在出现的对话框中,指定要更新的类或 JAR 文件的名称和位

置。您可以单击 " 浏览 " 来搜索它。

提示提示提示提示您还可以通过在 Java 类或 JAR 文件的属性页的 " 常规 " 选项卡上单击

" 立即更新 " 来更新它。

104

Page 119: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

❖ 更新类或更新类或更新类或更新类或 JAR (SQL)::::

1 以 DBA 权限连接到数据库。

2 执行以下语句:

INSTALL JAVA UPDATE[ JAR 'jarname' ]FROM FILE 'filename'

如果要更新 JAR,必须输入 JAR 在数据库中使用的名称。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > INSTALL 语句 "。

105

Page 120: Adaptive Server Anywhere

创建要保存 Java 对象的列

创建要保存创建要保存创建要保存创建要保存 Java 对象的列对象的列对象的列对象的列

本节介绍如何使数据类型为 Java 类的列适合标准的 SQL 框架。

创建创建创建创建 Java 数据类型的列数据类型的列数据类型的列数据类型的列

您可以将已安装的任何 Java 类用作数据类型。您必须使用全限定名表

示数据类型。

例如,下面的 CREATE TABLE 语句包含具有 Java 数据类型 asademo.Name 和 asademo.ContactInfo 的列。其中, Name 和 ContactInfo 是 asademo 包中的类。

CREATE TABLE jdba.customer(

id integer NOT NULL,company_name CHAR(35) NOT NULL,JName asademo.Name NOT NULL,JContactInfo asademo.ContactInfo NOT NULL,PRIMARY KEY (id)

)

区分大小写区分大小写区分大小写区分大小写 与其它 SQL 数据类型不同, Java 数据类型区分大小写。对于数据类型

的所有部分都必须提供正确的大小写。

对对对对 Java 列使用缺省值和列使用缺省值和列使用缺省值和列使用缺省值和 NULL

您可以对 Java 列使用缺省值, Java 列可以保存 NULL 条目。

Java 列和缺省值列和缺省值列和缺省值列和缺省值 列可以将任何具有正确数据类型的函数用作缺省值,

或者使用任何预置的缺省值。您可以将任何具有正确数据类型的函数(例如,与列属于相同的类)用作 Java 列的缺省值。

Java 列和列和列和列和 NULL Java 列可以允许使用 NULL。如果一个具有 Java 数据类型的可为空值的列没有缺省值,则该列包含 NULL。

106

Page 121: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

如果未设置 Java 值,则它具有 Java 空值。这个 Java 空值映射到 SQL NULL,您可以针对这些值使用 IS NULL 和 IS NOT NULL 搜索条件。

例如,假设未在名为 JProd 的列中设置 Product Java 对象的描述,您可

以按照以下方式查询其描述为空值的所有产品:

SELECT *FROM productWHERE JProd>>description IS NULL

107

Page 122: Adaptive Server Anywhere

插入、更新和删除 Java 对象

插入、更新和删除插入、更新和删除插入、更新和删除插入、更新和删除 Java 对象对象对象对象

本节介绍标准的 SQL 数据操作语句如何应用于 Java 列。

在整个这一节中,我们提供了具体的示例,这些示例以示例数据库的 Product 表和名为 Product 的类为依托,阐释了各个要点。您应当先在 SQL Anywhere 目录下查看 Samples\ASA\Java\\asademo\Product.java 文件。

创建创建创建创建 Java 示例表示例表示例表示例表 本节中的示例假定:您已经将 Java 表添加到了示例数据库中,而且,

您已经以用户 ID jDBA 和口令 SQL 进行了连接。

有关更多信息,请参阅 "" 设置 Java 示例 " 第 90 页 "。

示例类示例类示例类示例类

本节介绍了在后面几节中的示例中都会要用到的类。

下面这部分复制了 SQL Anywhere 目录下的 Samples\ASA\Java\asademo\Product.jave 文件中包括的 Product 类定义:

package asademo;public class Product implements java.io.Serializable { // public fields public String name ; public String description ; public String size ; public String color; public int quantity ; public java.math.BigDecimal unit_price ; // Default constructor Product () {

unit_price = new java.math.BigDecimal( 10.00 );name = "Unknown";size = "One size fits all";

} // Constructor using all available arguments Product ( String inColor,

String inDescription, String inName, int inQuantity,

108

Page 123: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

String inSize, java.math.BigDecimal inUnit_price ) {

color = inColor; description = inDescription; name = inName; quantity = inQuantity; size = inSize; unit_price=inUnit_price; } public String toString() { return size + " " + name + ": " + unit_price.toString(); }

注意注意注意注意 • Product 类有几个公共字段与 DBA.Product 表的一些列相对应,这

些列将被一起被收集到该类中。

• 提供 toString 方法是为了方便。当您将某个对象名包括在选择列

表中时,将执行 toString 方法并显示它的返回字符串。

• 某些方法的提供是为了设置和获取相应的字段。在面向对象的编

程中经常使用这些方法,而不是直接处理字段。在这里,这些字段是公共字段,这是为了在教程中用起来更方便。

插入插入插入插入 Java 对象对象对象对象

当您在具有 Java 列的表中 INSERT (插入)行时,需要将 Java 对象插

入到 Java 列中。

插入 Java 对象的方式有两种:从 SQL 插入,或者使用 JDBC 从其它在

数据库内运行的 Java 类插入。

从从从从 SQL 插入插入插入插入 Java 对象对象对象对象

您可以使用构造函数插入 Java 对象,也可以先用 SQL 变量构建一个 Java 对象然后将其插入。

使用构造函数插入对使用构造函数插入对使用构造函数插入对使用构造函数插入对象象象象

当您将值插入到具有 Java 类数据类型的列中时,您就是在插入 Java 对象。要插入具有正确的属性集的对象,新对象的任何公共字段值都必须正确,并且您需要调用任何用来设置 private 字段的方法。

109

Page 124: Adaptive Server Anywhere

插入、更新和删除 Java 对象

❖ 插入插入插入插入 Java 对象:对象:对象:对象:

• 按以下方式将 Product 类的新实例 INSERT 到 product 表中:

INSERTINTO product ( ID, JProd )VALUES ( 702, NEW asademo.Product() )

您可以在运行 jdemo.sql 脚本之后,从用户 ID jdba 针对示例

数据库运行该示例。

NEW 关键字为 asademo 包中的 Product 类激活缺省构造函数。

从从从从 SQL 变量插入对变量插入对变量插入对变量插入对

象象象象

您还可以在适当的类的 SQL 变量中逐个 (而不是通过构造函数)设置

对象的字段值。

❖ 使用使用使用使用 SQL 变量插入变量插入变量插入变量插入 Java 对象:对象:对象:对象:

1 创建类型为 Java 类的 SQL 变量:

CREATE VARIABLE ProductVar asademo.Product

2 使用类构造函数将新对象指派给该变量:

SET ProductVar = NEW asademo.Product()

3 向该对象的字段指派值 (如果需要):

SET ProductVar>>color = 'Black';SET ProductVar>>description = 'Steel tipped boots';SET ProductVar>>name = 'Work boots';SET ProductVar>>quantity = 40;SET ProductVar>>size = 'Extra Large';SET ProductVar>>unit_price = 79.99;

4 将该变量插入到表中:

INSERTINTO Product ( id, JProd )VALUES ( 800, ProductVar )

5 检查是否已插入该值:

110

Page 125: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

SELECT *FROM productWHERE id=800

6 撤消在本练习中所作的更改:

ROLLBACK

对于存储过程和其它使用 SQL 在数据库中建立编程逻辑的情况, SQL 变量的应用是一种典型情况。 Java 提供一种更强大的方式来完成该任

务。您可以联合使用服务器端 Java 类和 JDBC 来将对象插入到表中。

从从从从 Java 中插入对象中插入对象中插入对象中插入对象

您可以使用 JDBC prepared 语句将对象插入到表中。

prepared 语句使用占位符表示变量。然后,您可以使用 PreparedStatement 对象的 setObject 方法。

您可以使用 prepared 语句从客户端或服务器端 JDBC 插入对象。

有关使用 prepared 语句处理对象的更多信息,请参阅 "插入和检索对象 " 第 168 页。

更新更新更新更新 Java 对象对象对象对象

您可能希望按照下列任一方法来更新 Java 列的值:

• 更新整个对象。

• 更新该对象的某些字段。

更新整个对象更新整个对象更新整个对象更新整个对象 您可以按照与插入对象操作大体相同的方式来更新对象:

• 从 SQL 中,您可以使用构造函数将对象更新为新对象,就像是用

构造函数创建新对象一样。然后,如果需要,您可以更新各个字段。

• 从 SQL 中,可以使用 SQL 变量来保存所需的对象,然后更新用于

保存该变量的行。

111

Page 126: Adaptive Server Anywhere

插入、更新和删除 Java 对象

• 从 JDBC 中,可以使用 prepared 语句和 PreparedStatement.setObject 方法。

更新对象的字段更新对象的字段更新对象的字段更新对象的字段 对象的各个字段的数据类型与 SQL 数据类型相对应,使用的是 "ASA SQL 参考手册 > SQL 数据类型 > Java / SQL 数据类型转换 " 中描述的从 SQL 到 Java 的数据类型映射。

您可以使用标准的 UPDATE 语句来更新各个字段:

UPDATE ProductSET JProd.unit_price = 16.00WHERE ID = 302

在 初发布的数据库中的 Java 中,必须使用特殊函数 (EVALUATE) 来进行更新。现在已不需要这样做。

要更新 Java 字段,字段的 Java 数据类型必须映射到 SQL 类型:SET 子句右侧的表达式必须与该类型相匹配。您可能需要使用 CAST 函数来对

数据类型进行适当的转换。

有关 Java 和 SQL 之间的数据类型映射的更多信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > Java / SQL 数据类型转换 "。

使用使用使用使用 set 方法方法方法方法 在 Java 编程中,一种常见的做法是使用方法来获取并设置值,而不是

直接处理字段。另一种常见的做法是让这些方法返回 void。您可以在 SQL 中使用 set 方法来更新列:

UPDATE jdba.ProductSET JProd.setName( 'Tank Top')WHERE id=302

使用方法比直接处理字段慢,因为必须运行 Java VM。

有关更多信息,请参阅 "" 返回 void 的方法的返回值 " 第 122 页 "。

112

Page 127: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

删除删除删除删除 Java 对象、类和对象、类和对象、类和对象、类和 JAR 文件文件文件文件

删除包含 Java 对象的行与删除其它行完全一样。 DELETE 语句中的 WHERE 子句可包括 Java 对象或 Java 字段和方法。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > DELETE 语句 "。

使用 Sybase Central,也可以删除整个 Java 类或 JAR 文件。

❖ 删除删除删除删除 Java 类或类或类或类或 JAR 文件文件文件文件 (Sybase Central)::::

1 打开 Java Objects 文件夹。

2 查找希望删除的类或 JAR。

3 右击该类或 JAR 文件,然后从弹出式菜单中选择 " 删除 "。

另请参阅

• " 安装类 " 第 101 页

• " 安装 JAR" 第 102 页

113

Page 128: Adaptive Server Anywhere

查询 Java 对象

查询查询查询查询 Java 对象对象对象对象

您可能希望按照下列任一方法来检索 Java 列的值:

• 检索整个对象。

• 检索对象的一些字段。

检索整个对象检索整个对象检索整个对象检索整个对象 从 SQL 中,可创建具有适当类型的变量,然后将值从对象选择到该变

量中。但是,您想使用整个对象的确切位置就是在 Java 应用程序中。

您可以使用一个查询的 ResultSet 的 getObject 方法,将对象检索到服

务器端 Java 类中。还可以将对象检索到客户端 Java 应用程序。

有关使用 JDBC 检索对象的更多信息,请参阅 " 使用 JDBC 的查询 " 第165 页。

检索对象的字段检索对象的字段检索对象的字段检索对象的字段 对象的各个字段的数据类型与 SQL 数据类型相对应,使用的是 "ASA SQL 参考手册 > SQL 数据类型 > Java / SQL 数据类型转换 " 中描述的从 SQL 到 Java 的数据类型映射。

• 您可以通过在一个查询的选择列表中包括字段来检索各个字段,

正如下面的简单示例所示:

SELECT JProd>>unit_priceFROM productWHERE ID = 400

• 如果使用方法来设置和获取字段的值 (这是面向对象编程中的常

用做法),则可以在查询中包括 getField 方法:

SELECT JProd>>getName()FROM ProductWHERE ID = 401

有关在 WHERE 子句中使用对象以及比较对象时的其它问题的更多信

息,请参阅 "" 比较 Java 字段和对象 " 第 116 页 "。

114

Page 129: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

性能提示性能提示性能提示性能提示由于调用方法时需要启动 Java VM,所以,与激活用于获取字段的方法

相比,直接获取字段较快。

SELECT 列名的结列名的结列名的结列名的结

果果果果

您可以在查询选择列表中列出列名,正如下面的查询中所示:

SELECT JProdFROM jdba.product

该查询将 Sun 的对象序列化返回到客户端应用程序。

当您在 Interactive SQL 中执行检索对象的查询时,它显示对象的 toString 方法的返回值。对于 Product 类, toString 方法用一个字符串列

出对象的大小、名称和单价。该查询的结果如下:

JProd

Small Tee Shirt: 9.00

Medium Tee Shirt: 14.00

One size fits all Tee Shirt: 14.00

One size fits all Baseball Cap: 9.00

One size fits all Baseball Cap: 10.00

One size fits all Visor: 7.00

One size fits all Visor: 7.00

Large Sweatshirt: 24.00

Large Sweatshirt: 24.00

Medium Shorts: 15.00

115

Page 130: Adaptive Server Anywhere

比较 Java 字段和对象

比较比较比较比较 Java 字段和对象字段和对象字段和对象字段和对象

公共 Java 类是比传统的 SQL 域更丰富的域。与基于传统的 SQL 数据类

型的列相比,这提出了有关 Java 列如何在关系数据库中运行的问题。

特别是如何比较对象这一问题会影响以下各方面:

• 用 ORDER BY 子句、 GROUP BY 子句、 DISTINCT 关键字或使

用集合函数进行的查询。

• 使用等式或不等式比较条件的语句。

• 索引和唯一列。

• 主键列和外键列。

比较比较比较比较 Java 对象的方对象的方对象的方对象的方

法法法法

无论是在查询中还是在索引中,对行进行分类和排序都意味着对各个行上的值进行比较。如果您有一个 Java 列,则可以按照下列方式执行比

较:

• 在公共字段上比较在公共字段上比较在公共字段上比较在公共字段上比较 您可以按照在常规行上进行比较的方法来在

公共字段上进行比较。例如,可执行下列查询:

SELECT name, JProd.unit_priceFROM ProductORDER BY JProd.unit_price

可在查询中使用这种比较,但是对于索引和键列不能使用这种方式。

• 使用使用使用使用 compareTo 方法进行比较方法进行比较方法进行比较方法进行比较 可以比较已经实现了 compareTo 方法的 Java 对象。JProd 列所基于的 Product 类有一个 compareTo 方法,该方法可根据 unit_price 字段比较对象。这允许执行下面的

查询:

SELECT name, JProd.unit_priceFROM ProductORDER BY JProd

ORDER BY 子句所需的比较基于 compareTo 方法自动执行。

116

Page 131: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

比较比较比较比较 Java 对象对象对象对象

要比较两个类型相同的对象,必须实现 compareTo 方法:

• 对于要用作主键、索引或唯一列的 Java 数据类型的列,该列的类

必须实现 compareTo 方法。

• 要在查询中使用 ORDER BY、GROUP BY 或 DISTINCT 子句,必

须比较列的值。要使这些子句中的任何一个生效,列的类必须有一个 compareTo 方法。

• 那些使用比较的函数 (如 MAX 和 MIN),只能用于具有 compareTo 方法的 Java 类。

compareTo 方法的方法的方法的方法的

要求要求要求要求

compareTo 方法必须具有下列属性:

• 作用域作用域作用域作用域 该方法必须能够从外部看到,因此应当是 public 方法。

• 参数参数参数参数 该方法带有一个参数,该参数是当前类型的对象。当前对

象与所提供的对象进行比较。例如, Product.compareTo 具有以

下参数:

compareTo( Product anotherProduct )

该方法将类型为 Product 的 anotherProduct 对象与当前对象进行比

较。

• 返回值返回值返回值返回值 compareTo 方法必须返回 int 数据类型,其含义如下:

• 负整数负整数负整数负整数 当前对象小于所提供的对象。建议您对于这种情况

返回 -1 以便与 Java 基类中的 compareTo 方法兼容。

• 零零零零 当前的对象与所提供的对象具有相同的值。

• 正整数正整数正整数正整数 当前对象大于所提供的对象。建议您对于这种情况

返回 1 以便与 Java 基类中的 compareTo 方法兼容。

示例示例示例示例 安装到具有示例类的示例数据库中的 Product 类有一个 compareTo 方法,具体细节如下:

117

Page 132: Adaptive Server Anywhere

比较 Java 字段和对象

public int compareTo( Product anotherProduct ) { // Compare first on the basis of price // and then on the basis of toString() int lVal = unit_price.intValue(); int rVal = anotherProduct.unit_price.intValue(); if ( lVal > rVal ) { return 1; } else if (lVal < rVal ) { return -1; } else { return toString().compareTo( anotherProduct.toString() );{ } } }

该方法比较每个对象的单价。如果单价相同,则比较名称 (使用 Java 字符串比较,而不是数据库字符串比较)。在进行比较时,只有两个对象的单价和名称都相同时,它们才被视为相同。

使使使使 toString 和和和和 compareTo 兼容兼容兼容兼容

当您在查询的选择列表中包括一个 Java 列并在 Interactive SQL 中执行它

时,将显示 toString 方法的值。在比较列时使用的方法是 compareTo。如果 toString 方法和 compareTo 方法的实现方式彼此不一致,结果就会

不正确,例如, DISTINCT 查询看起来会返回重复的行。

例如,假定示例数据库中的 Product 类有一个返回了产品名称的 toString 方法和一个基于价格的 compareTo 方法。那么,在 Interactive SQL 中执行的以下查询将显示重复值:

SELECT DISTINCT JProdFROM product

JProd

Tee Shirt

Tee Shirt

Baseball Cap

Visor

118

Page 133: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

在这里,所显示的返回值由 toString 确定。 DISTINCT 关键字消除由 compareTo 确定的重复项。由于两个方法按照互不相关的方式实现,因

此看起来已返回重复的行。

Sweatshirt

Shorts

JProd

119

Page 134: Adaptive Server Anywhere

数据库中 Java 类的特殊功能

数据库中数据库中数据库中数据库中 Java 类的特殊功能类的特殊功能类的特殊功能类的特殊功能

本节介绍在数据库中使用的 Java 类的功能。

支持的类支持的类支持的类支持的类

并非 JDK 中的所有类您都能使用。可用于数据库服务器中的运行时 Java 类属于 Java API 的一个子集。

有关支持的包的更多信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > 受支持的 Java 包 "。

调用调用调用调用 main 方法方法方法方法

通常,通过对具有 main 方法的类运行 Java VM 来启动 Java 应用程序

(在数据库外部)。

例如, SQL Anywhere 目录下 Samples\ASA\Java\JDBCExamples.java 文件中的 JDBCExamples 类有一个 main 方法。当您从命令行使用下面这样的命令执行类时,执行

的是 main 方法:

java JDBCExamples

有关如何运行 JDBCExamples 类的更多信息,请参阅 "建立 JDBC 连接 " 第 153 页。

❖ 从从从从 SQL 调用类的调用类的调用类的调用类的 main 方法:方法:方法:方法:

1 声明将字符串数组作为参数的方法:

public static void main( java.lang.String[] args ){...}

2 使用 CALL 语句激活 main 方法。

120

Page 135: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

字符串数组的每个成员都必须是 CHAR 或 VARCHAR 数据类型

或文字串。

示例示例示例示例 下面的类包含一个按反序写出参数的 main 方法:

public class ReverseWrite { public static void main( String[] args ){ int i: for( i = args.length; i > 0 ; i-- ){ System.out.print( args[ i-1 ] ); } }}

您可以按以下方式从 SQL 执行该方法:

call ReverseWrite.main( ' one', ' two', 'three' )

数据库服务器窗口显示输出结果:

three two one

在在在在 Java 应用程序中使用线程应用程序中使用线程应用程序中使用线程应用程序中使用线程

利用 java.lang.Thread 包的功能,可以在 Java 应用程序中使用多个线

程。每个 Java 线程都是一个引擎线程,并且都来自 -gn 数据库服务器选

项允许的线程数。

您可在 Java 应用程序中同步、挂起、重新开始、中断或停止线程。

有关数据库服务器线程的更多信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > -gn 服务器选项 "。

JDBC 调用的序列化调用的序列化调用的序列化调用的序列化 对服务器端 JDBC 驱动程序发出的所有调用都被序列化,这样,在任何

时刻都只有一个线程处于活动状态并执行着 JDBC。

121

Page 136: Adaptive Server Anywhere

数据库中 Java 类的特殊功能

" 未找到过程未找到过程未找到过程未找到过程 " 错误错误错误错误

如果在调用 Java 方法时所提供的参数数量不正确,或者如果所使用的

数据类型不正确,服务器将响应 " 未找到过程 " 错误。您应当检查参数

的数量和类型。

有关 SQL 和 Java 之间类型转换的更多信息,请参阅 "ASA SQL 参考手

册 > SQL 数据类型 > Java / SQL 数据类型转换 "。

返回返回返回返回 void 的方法的返回值的方法的返回值的方法的返回值的方法的返回值

您可以在能够使用表达式的 SQL 语句中使用 Java 方法。您必须确保 Java 方法返回的数据类型映射到相应的 SQL 数据类型。

有关 Java/SQL 数据类型映射的更多信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > Java / SQL 数据类型转换 "。

但是,当方法返回 void 时,值 this 返回到 SQL ;即,对象本身。该功

能只影响从 SQL (而不是从 Java)发出的调用。

该功能在 UPDATE 语句中尤其有用,其中 set 方法通常返回 void。您可

以在示例数据库中使用以下 UPDATE 语句:

update jdba.productset JProd = JProd.setName('Tank Top')where id=302

setName 方法返回 void,因此会把产品对象隐式地返回到 SQL。

从从从从 Java 方法返回结果集方法返回结果集方法返回结果集方法返回结果集

本节介绍如何能够从 Java 方法使用结果集。您必须编写一个能够向调

用环境返回结果集的 Java 方法,并将该方法包装在一个被声明为 LANGUAGE JAVA 的 EXTERNAL NAME 的 SQL 存储过程中。

❖ 从一个从一个从一个从一个 Java 方法返回结果集:方法返回结果集:方法返回结果集:方法返回结果集:

1 确保在一个公共类中将 Java 方法声明为公共的和静态的。

122

Page 137: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

2 对于您期望该方法返回的每个结果集,确保该方法都有一个 java.sql.ResultSet[] 类型的参数。这些结果集参数都必须出现在

参数列表的末尾。

3 在该方法中,首先创建 java.sql.ResultSet 的实例,然后将其指

派给上述 ResultSet[] 参数之一。

4 创建类型为 EXTERNAL NAME LANGUAGE JAVA 的 SQL 存储

过程。该类型的过程是 Java 方法的包装。您可以对 SQL 过程

结果集使用游标,方法与任何其它返回结果集的过程相同。

有关那些用作 Java 方法包装的存储过程的语法的更多信息,请

参阅 "ASA SQL 参考手册 > SQL 语句 > CREATE PROCEDURE 语句 "。

示例示例示例示例 下面的简单类有一个方法,该方法执行查询并将结果集返回给调用环境。

import java.sql.*;public class MyResultSet { public static void return_rset( ResultSet[] rset1 ) throws SQLException { Connection conn = DriverManager.getConnection( "jdbc:default:connection" ); Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery ( "SELECT CAST( JName.lastName " + "AS CHAR( 50 ) )" + "FROM jdba.contact " ); rset1[0] = rset; }}

您可以使用 CREATE PROCEDURE 语句暴露结果集,该语句指示从过

程返回的结果集的数量以及 Java 方法的 " 签名签名签名签名 "。

可以像下面这样定义一个指示结果集的 CREATE PROCEDURE 语句:

CREATE PROCEDURE result_set() DYNAMIC RESULT SETS 1 EXTERNAL NAME 'MyResultSet.return_rset ([Ljava/sql/ResultSet;)V' LANGUAGE JAVA

123

Page 138: Adaptive Server Anywhere

数据库中 Java 类的特殊功能

您可以对该过程打开游标,就好像对任何返回结果集的 ASA 过程一

样。

字符串 (Ljava/sql/ResultSet;)V 是 Java 方法签名,它是参数和返回值的

数量和类型的压缩字符表示形式。

有关 Java 方法签名的更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > CREATE PROCEDURE 语句 "。

通过存储过程从通过存储过程从通过存储过程从通过存储过程从 Java 返回值返回值返回值返回值

您可以将使用 EXTERNAL NAME LANGUAGE JAVA 创建的存储过程

用作 Java 方法的包装。本节介绍如何编写 Java 方法以便在存储过程中

利用 OUT 或 INOUT 参数。

Java 不显式支持 INOUT 或 OUT 参数。相反,您可以使用参数数组。例

如,要使用整数 OUT 参数,请创建一个只包含一个整数的数组:

public class TestClass { public static boolean testOut( int[] param ){ param[0] = 123; return true; }}

下面的过程使用 testOut 方法:

CREATE PROCEDURE sp_testOut ( OUT p INTEGER )EXTERNAL NAME 'TestClass/testOut ([I)Z'LANGUAGE JAVA

字符串 ([I]Z 是一个 Java 方法签名,该签名指示:该方法有一个由整数

数组构成的参数,且会返回一个布尔值。您必须相应地定义该方法,使要用作 OUT 或 INOUT 参数的方法参数是 Java 数据类型的数组,该 Java 数据类型与 OUT 或 INOUT 参数的 SQL 数据类型相对应。

有关语法(包括方法签名)的更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > CREATE PROCEDURE 语句 "。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 数据类型 > Java / SQL 数据类型转换 "。

124

Page 139: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

Java 的安全管理的安全管理的安全管理的安全管理

Java 提供安全管理器,您可以使用它控制用户对应用程序的那些安全敏

感功能 (如文件访问和网络访问)的访问。 Adaptive Server Anywhere 对数据库中的 Java 安全管理器提供以下支持:

• Adaptive Server Anywhere 提供缺省的安全管理器。

• 您可以提供自己的安全管理器。

有关信息,请参阅 "" 实现您自己的安全管理器 " 第 126 页 "。

缺省的安全管理器缺省的安全管理器缺省的安全管理器缺省的安全管理器 缺省的安全管理器是 com.sybase.asa.jrt.SAGenericSecurityManager 类。它执行下列任务:

1. 它检查 JAVA_INPUT_OUTPUT 数据库选项的值。

2. 它检查数据库服务器是否通过使用 -sc 数据库服务器选项在 C2 安全

模式下启动。

3. 如果连接属性为 OFF,则不允许访问 Java 文件 I/O 功能。

4. 如果数据库服务器是在 C2 安全模式下运行,则不允许访问 java.net 包。

5. 当安全管理器阻止用户访问功能时,它返回 java.lang.SecurityException。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 > JAVA_INPUT_OUTPUT 选项 [database]" 和 "ASA 数据库管理指南 > 数据

库服务器 > -sc 服务器选项 "。

使用缺省安全管理器使用缺省安全管理器使用缺省安全管理器使用缺省安全管理器控制控制控制控制 Java 文件的文件的文件的文件的 I/O

Java 文件的 I/O 是通过 JAVA_INPUT_OUTPUT 数据库选项控制的。该

选项在缺省情况下设置为 OFF,即不允许执行文件 I/O。

❖ 使用缺省安全管理器允许文件访问:使用缺省安全管理器允许文件访问:使用缺省安全管理器允许文件访问:使用缺省安全管理器允许文件访问:

• 将 JAVA_INPUT_OUTPUT 选项设置为 ON:

SET OPTION JAVA_INPUT_OUTOUT='ON'

125

Page 140: Adaptive Server Anywhere

数据库中 Java 类的特殊功能

实现您自己的安全管理器实现您自己的安全管理器实现您自己的安全管理器实现您自己的安全管理器

要实现您自己的安全管理器,需要执行若干步骤。

❖ 提供自己的安全管理器:提供自己的安全管理器:提供自己的安全管理器:提供自己的安全管理器:

1 实现一个可扩展 java.lang.SecurityManager 的类。

SecurityManager 类有许多方法可用于检查是否允许执行某种特

定的操作。如果允许执行该操作,则方法将以静默方式返回。如果该方法返回一个值,则抛出 SecurityException。

您必须将用于控制要允许的操作的方法替换为以静默方式返回的方法。您可以通过实现 public void 方法达到目的。

2 向安全管理器指派适当的用户。

您可以使用 add_user_security_manager、

update_user_security_manager 和 delete_user_security_manager 系统存

储过程来给用户指派安全管理器。例如,如果要将 MySecurityManager 类指派为用户的安全管理器,将执行以下命

令:

call dbo.add_user_security_manager( user_name, 'MySecurityManager', NULL )

示例示例示例示例 下面的类允许从文件进行读取但不允许写入:

public class MySecurityManager extends SecurityManager{ public void checkRead(FileDescriptor) {} public void checkRead(String) {} public void checkRead(String, Object) {}}

SecurityManager.checkWrite 方法没有被重载,因此禁止对文件执行写

操作。 checkRead 方法改以静默方式返回,容许执行读操作。

126

Page 141: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

如何存储如何存储如何存储如何存储 Java 对象对象对象对象

Java 值以序列化形式存储。这意味着每一行都包含下列信息:

• 版本标识符。

• 存储的类 (或子类)的标识符。

• 类中非静态、非瞬时字段的值。

• 其它开销信息。

类定义并不 对每一行分别存储。标识符提供对类定义的引用,而类定

义只保存一份。

使用 Java 对象时,您不必知道它们如何工作的详情,但是,这些对象

的存储方法确实会影响性能。请看下面信息。

注意注意注意注意 • 磁盘空间磁盘空间磁盘空间磁盘空间 每一行的开销为 10 到 15 个字节。如果该类有一个变

量,则开销所需的存储空间量可能会与变量本身所需的存储空间量相近。如果该类有许多变量,则开销是可忽略的。

• 性能性能性能性能 当您每次插入或更新 Java 值时, Java VM 需要将其序列

化。每次在查询中检索 Java 值时,都需要由 VM 对其进行反序列

化。这会对性能造成很大影响。

您可以通过使用计算列来避免在查询时影响性能。

• 索引索引索引索引 相对于简单的 SQL 数据类型上的索引,在 Java 列上建索

引并不是很可取的,也不会在性能方面带来什么好处。

• 序列化序列化序列化序列化 如果类有一个 readObject 或 writeObject 方法,则在反序

列化或序列化实例时将相对应地调用它们。由于将激活 Java VM,

所以,使用 readObject 或 writeObject 方法可能会影响性能。

127

Page 142: Adaptive Server Anywhere

如何存储 Java 对象

Java 对象和类版本对象和类版本对象和类版本对象和类版本

存储在数据库中的 Java 对象是 " 持久的持久的持久的持久的 " ;这就是说,即使在没有代码

运行时,它们也存在。这意味着您可以执行下列操作:

1. 安装一个类。

2. 创建一个将该类用作列的数据类型的表。

3. 在表中插入行。

4. 安装该类的新版本。

那么,新版本的类定义是如何对已存在的行起作用的呢?

在类更新后访问行在类更新后访问行在类更新后访问行在类更新后访问行 Adaptive Server Anywhere 提供一种类版本控制形式,来允许将新类与旧

行一起使用。访问这些旧值所依照的规则如下:

• 如果可序列化的字段位于旧版本的类中,但是在新版本中它或者

没有定义,或者不能序列化,则该字段将被忽略。

• 如果可序列化的字段位于新版本的类中,但是它在旧版本中或者

没有定义,或者不能序列化,则该字段将被初始化为缺省值。对于各原始数据类型,缺省值为 0 ;布尔类型缺省值为 false ;

NULL 是对象引用的缺省值。

• 如果有一个旧版本的超级类 (非新版本的超级类),则该超级类

的数据被忽略。

• 如果有一个新版本的超级类 (非旧版本的超级类),则该超级类

的数据被初始化为缺省值。

• 如果新旧版本之间的可序列化字段的类型不同,则该字段被初始

化为缺省值。不支持类型转换;这与 Sun Microsystems 的序列化

一致。

何时无法访问对象何时无法访问对象何时无法访问对象何时无法访问对象 如果序列化对象的类或者它的任何超级类已在某个时候从数据库中删除,则不能访问该对象。这种行为与 Sun Microsystems 的序列化一致。

在数据库之间移动对在数据库之间移动对在数据库之间移动对在数据库之间移动对象象象象

前面对象旧值更改规则使得在数据库之间转移对象成为可能,即使类的版本不同也无妨。数据库之间的对象转移可发生在下面情形:

• 将对象复制到远程数据库。

128

Page 143: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

• 将对象的表卸载并重装到另一个数据库中。

• 针对另一个数据库转换并应用包含对象的日志文件。

何时使用新类何时使用新类何时使用新类何时使用新类 在每个类首次使用时,每个连接的 VM 都装载该类的类定义。

当您 INSTALL (安装)类时,将隐式重新启动您的连接的 VM。因此,

您可随时访问新类。

对于执行 INSTALL 的连接以外的连接,该新类会在下一次一个 VM 首次访问该类时装载。如果该类已由 VM 装载,则直到为该连接重新启动

该 VM (例如,使用 STOP JAVA 和 START JAVA)后,该连接才能看

到该新类。

129

Page 144: Adaptive Server Anywhere

Java 数据库设计

Java 数据库设计数据库设计数据库设计数据库设计

有大量的理论和实践经验可用来帮助您设计关系数据库。您不仅可以找到对 " 实体 - 关系 " 设计和其它设计方法的入门级材料 (请参阅 "ASA SQL 用户指南 > 设计数据库 "),而且可以找到更深入讲解有关内容的

书籍。

在开发对象 - 关系数据库方面,并没有这么多类似的理论和实践经验;

在开发 Java- 关系数据库方面,毫无疑问也是如此。下面,我们对于如

何使用 Java 来加强关系数据库的实践应用提供一些建议。

关系数据和面向对象的数据的实体和属性关系数据和面向对象的数据的实体和属性关系数据和面向对象的数据的实体和属性关系数据和面向对象的数据的实体和属性

在关系数据库设计中,每个表都描述一个 " 实体实体实体实体 "。例如,在示例数据

库中,有名为 Employee、 Customer、 Sales_order 和 Department 的表。这些

实体的属性成为表的列:职员地址、客户标识号、销售订单日期等。可以将表的每一行视为实体的一个单独实例蜒特定的职员、销售订单或部门。

在面向对象的编程中,每个类都描述一个实体,该类的方法和字段描述该实体的属性。该类的每个实例 (每个 " 对象对象对象对象 ")都包含该实体的一个

单独实例。

因此,这对于要基于 Java 类的关系列似乎有些勉强,表和类之间的对

应似乎更合理。

现实世界中的实体和属性现实世界中的实体和属性现实世界中的实体和属性现实世界中的实体和属性

实体和属性之间的区别听起来很清晰,但稍作思考,就会发现在实践中这种区别往往并不清晰:

• 地址可被视为客户的属性,但是地址也是具有自己的街道、城市

等属性的实体。

• 价格可被视为产品的属性,但是也可以被视为一个实体,其属性

是数量和货币。

130

Page 145: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

对象 - 关系数据库的意义就在于可以用两种方式表示实体这一事实。您

可以将一些实体表示为表,将另一些实体表示为表中的类。下一节将介绍一个示例。

关系数据库限制关系数据库限制关系数据库限制关系数据库限制

假设有一个保险公司希望对其客户进行跟踪记录。客户可以被视为实体,所以,这自然需要构造一个包含公司所有客户的表。

但是,保险公司要与各种客户交往,如投保人、保险受益人以及负责支付保费的人。针对上述各种客户类型,保险公司分别需要不同的信息。对于受益人,除了地址,几乎不需要其它信息。对于投保人,需要健康信息。对于支付保费的客户,可能需要与纳税相关的信息。

是分别将各种类型的客户作为不同实体来处理?还是将客户类型作为客户的属性来处理?哪一种做法较好呢?两种方法都有局限性:

• 如果为每种客户建立单独的表,不仅会导致数据库的设计非常复

杂,而且,一旦需要与所有客户有关的信息,就要进行多表查询。

• 如果使用单一的客户表,则很难确保每个客户的信息正确无误。

如果让列对于有些客户而言是必需的,而对于另一些客户则可以为空,那么,就允许输入正确的数据,但并不强制输入。在关系数据库中,没有任何简便方法能够使缺省行为与新条目的某种属性相关联。

使用类克服关系数据库限制使用类克服关系数据库限制使用类克服关系数据库限制使用类克服关系数据库限制

在使用单个客户表时,用 Java 类列表示某些信息,可以克服关系数据

库的限制。

例如,假定对于投保人和受益人需要不同的联系信息,您可以通过定义一个基于 ContactInformation 类的列来达到此目的。然后,定义名称分

别为 HolderContactInformation 和 BeneficiaryContactInformation 的ContactInformation 类的子类。通过按类型输入新客户,您可以确保信

息正确无误。

131

Page 146: Adaptive Server Anywhere

Java 数据库设计

关系数据的抽象级别关系数据的抽象级别关系数据的抽象级别关系数据的抽象级别

可按照用途对关系数据库中的数据进行分类。这些数据中哪些属于 Java 类,哪些 适合保存在简单数据类型的列中呢?

• 参照完整性列参照完整性列参照完整性列参照完整性列 主键列和外键列通常保存标识号。这些标识号可

以被称作 " 参照参照参照参照 " 数据,因为它们主要定义数据库的结构以及表

之间的关系。

参照数据通常不属于 Java 类。尽管您可以使 Java 类列成为主键

列,但是对于此用途,整数和其它简单数据类型的效率可能更高。

• 索引数据索引数据索引数据索引数据 通常需要建索引的列也可能不属于 Java 类。但是,需

要建索引的数据和无须建索引的数据之间的界限定义得比较模糊。

利用计算列,您可以有选择地针对 Java 字段或方法 (或者实际上

是某种别的表达式)建索引。如果您在定义了 Java 类列之后发现

针对该列的字段或方法建索引有意义,则可以使用计算列来从该字段或方法另创建一个列。

有关更多信息,请参阅 "" 使用具有 Java 类的计算列 " 第 133 页 "。

• 描述性数据描述性数据描述性数据描述性数据 通常,每一行中都有一些数据是描述性的。这些数

据不用于参照完整性目的,而且可能不常需要建索引,但这些数据通常用在查询中。对于职员表,这可能包括诸如开始日期、地址、津贴信息、薪水等。如果将这些数据合并到数量更少的 Java 类数据类型的列中,通常会更好。

对于在单个关系列和关系表之间的级别的抽象,可以使用 Java 类来进

行。

132

Page 147: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

使用具有使用具有使用具有使用具有 Java 类的计算列类的计算列类的计算列类的计算列

计算列这一功能可以使 Java 数据库的设计更简便,使现有数据库更容

易利用 Java 功能,并提高 Java 数据类型的性能。

计算列的值是从其它列获取的。您不能在计算列中 INSERT (插入)或 UPDATE (更新)值。但是,任何尝试修改计算列的更新操作都会触发

与该列关联的触发器。

使用计算列使用计算列使用计算列使用计算列 具有 Java 类的计算列有两种主要用途:

• 分解分解分解分解 Java 列列列列 如果您创建一个使用 Java 类数据类型的列,则使用

计算列可以为该类的任一字段建索引。您可以添加一个计算列来保存该字段的值,并创建该字段的索引。

• 向关系表中添加向关系表中添加向关系表中添加向关系表中添加 Java 列列列列 如果您希望在尽可能不干扰现有数据库

的情况下使用 Java 类的一些功能,则可以将 Java 列作为计算列来

添加,并从表中的其它列中收集该列的值。

定义计算列定义计算列定义计算列定义计算列

计算列是在 CREATE TABLE 或 ALTER TABLE 语句中声明的。

创建具有计算列的表创建具有计算列的表创建具有计算列的表创建具有计算列的表 下面的 CREATE TABLE 语句用于创建 Java 示例表中的 product 表:

CREATE TABLE product( id INTEGER NOT NULL, JProd asademo.Product NOT NULL, name CHAR(15) COMPUTE ( JProd>>name ), PRIMARY KEY ("id"))

向表中添加计算列向表中添加计算列向表中添加计算列向表中添加计算列 下面的语句通过添加另一个计算列来变更 product 表:

ALTER TABLE productADD inventory_Value INTEGER COMPUTE ( JProd.quantity * JProd.unit_price )

修改计算列的表达式修改计算列的表达式修改计算列的表达式修改计算列的表达式 您可以使用 ALTER TABLE 语句更改计算列中使用的表达式。下面的语

句更改计算列所基于的表达式。

133

Page 148: Adaptive Server Anywhere

使用具有 Java 类的计算列

ALTER TABLE table_nameALTER column-name SET COMPUTE ( expression )

在执行上述语句时,将重新计算该列。如果新表达式无效,则 ALTER TABLE 语句失败。

下面的语句禁止某个列成为计算列。

ALTER TABLE table_nameALTER column-name DROP COMPUTE

在执行这个语句时,该列中的值不发生变化。

插入和更新计算列插入和更新计算列插入和更新计算列插入和更新计算列

计算列对有效的 INSERT 和 UPDATE 语句产生一些影响。 Java 示例表

中的 jdba.product 表有一个用于阐释问题的计算列 (name)。该表的定义如

下:

CREATE TABLE "jdba"."product"(

"id" INTEGER NOT NULL,"JProd" asademo.Product NOT NULL,"name" CHAR(15) COMPUTE( JProd.name ),PRIMARY KEY ("id")

)

• 不要直接插入或更新不要直接插入或更新不要直接插入或更新不要直接插入或更新 不能直接将值插入到计算列中。下面的语

句将失败并且同时会显示 " 重复的插入列 " 错误:

-- Incorrect statementINSERT INTO PRODUCT (id, name)VALUES( 3006, 'bad insert statement' )

同样, UPDATE 语句不能直接更新计算列。

• 列出列名列出列名列出列名列出列名 您每次都必须在 INSERT 语句中指定具有计算列的表

的列名。下面的语句会失败,并会显示 "INSERT 的值数目错误 " 这一消息:

-- Incorrect statementINSERT INTO PRODUCTVALUES( 3007,new asademo.Product() )

134

Page 149: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

您必须按照以下方式列出这些列:

INSERT INTO PRODUCT( id, JProd )VALUES( 3007,new asademo.Product() )

• 触发器触发器触发器触发器 您可以对计算列定义触发器,任何影响该列的 INSERT 或 UPDATE 语句都将触发触发器。

何时对计算列重新进行计算何时对计算列重新进行计算何时对计算列重新进行计算何时对计算列重新进行计算

在下列情况下对计算列重新进行计算:

• 删除、添加或重命名了列。

• 重命名了表。

• 修改了任何列的数据类型或 COMPUTE 子句。

• 插入了行。

• 更新了行。

在进行查询时不 对计算列重新进行计算。如果您使用与时间相关的表

达式,或者使用一个在其它某方面依赖数据库状态的表达式,则计算列可能无法给出正确的结果。

135

Page 150: Adaptive Server Anywhere

为 Java 配置内存

为为为为 Java 配置内存配置内存配置内存配置内存

本节介绍在数据库中运行 Java 的内存要求以及如何设置服务器以满足

这些要求。

Java VM 需要大量高速缓存。

有关调整高速缓存的信息,请参阅 "ASA SQL 用户指南 > 监控和提高性

能 > 使用高速缓存提高性能 "。

数据库和连接级别的数据库和连接级别的数据库和连接级别的数据库和连接级别的要求要求要求要求

Java VM 既基于每个数据库使用内存,又基于每个连接使用内存。

• 基于每个数据库的要求是不 " 可重定位可重定位可重定位可重定位 " 的:不能将它们以页面方

式调出到磁盘上。它们必须适应服务器高速缓存。这种类型的内存不是针对服务器的;它是针对每个数据库的。在估计高速缓存要求时,您必须汇总在服务器上运行的每个数据库的要求。

• 每个连接的要求是可重定位的,但是只能作为一个单位进行重定

位。一个连接的要求要么全部位于高速缓存中,要么全部位于临时文件中。

如何使用内存如何使用内存如何使用内存如何使用内存

数据库中的 Java 在以下几种情况下需要内存:

• 如果在服务器正在运行时首次使用 Java, VM 将装载到内存中,

这样就需要 1.5 Mb 以上的内存。这是数据库范围内的要求的一部

分。对于每一个使用 Java 的数据库,还会另外再装载一个 VM。

• 为每一个使用 Java 的连接装载 VM 的一个新实例。每个连接的新

实例大约需要 200K 内存。

• Java 应用程序中使用的每个类定义都装载到内存中。这将保存在

数据库范围的内存中:各个连接不需要单独的副本。

• 每个连接都需要一组有效的 Java 变量和应用程序堆栈空间 (用于

方法参数等)。

管理内存管理内存管理内存管理内存 您可以通过下列方法来控制内存的使用:

136

Page 151: Adaptive Server Anywhere

第 4 章 在数据库中使用 Java

• 设置总高速缓存大小设置总高速缓存大小设置总高速缓存大小设置总高速缓存大小 您所使用的高速缓存大小必须足以满足对

不能重定位的内存的全部需求。

高速缓存大小是在使用 -c 选项启动服务器时设置的。

在许多情况下, 8 Mb 高速缓存已足够。

• 设置命名空间大小设置命名空间大小设置命名空间大小设置命名空间大小 Java 命名空间大小是基于数据库的内存分配

的 大字节大小。

您可以使用 JAVA_NAMESPACE_SIZE 选项来设置它。该选项是

全局选项,且只能由具有 DBA 权限的用户进行设置。

• 设置堆大小设置堆大小设置堆大小设置堆大小 该 JAVA_HEAP_SIZE 选项设置基于连接的内存的

大字节大小。

该选项可针对单个连接进行设置,但是由于它影响可用于其它用户的内存,因此它只能由具有 DBA 权限的用户设置。

启动和停止启动和停止启动和停止启动和停止 VM 除了可以为 Java 设置内存参数以外,您还可以在不使用 Java 时,使用 STOP JAVA 语句来卸载 VM。只有具有 DBA 权限的用户才能执行该语

句。其语法就是:

STOP JAVA

VM 是在每次执行 Java 操作时装载的。如果您希望显式装载它以便为执

行 Java 操作做准备,则可以通过执行下面的语句来达到此目的:

START JAVA

137

Page 152: Adaptive Server Anywhere

为 Java 配置内存

138

Page 153: Adaptive Server Anywhere

第 5 章

使用使用使用使用 JDBC 访问数据访问数据访问数据访问数据

关于本章关于本章关于本章关于本章 本章说明如何使用 JDBC 访问数据。

您既可从客户端应用程序使用 JDBC,也可从数据库内部使用 JDBC。在数据库中加入编程逻辑时,使用 JDBC 的 Java 类也可以起到 SQL 存储过程的作用,而且功能比 SQL 存储过程更强。

139

Page 154: Adaptive Server Anywhere

JDBC 概述

JDBC 概述概述概述概述

JDBC 为 Java 应用程序提供了 SQL 接口:如果您要从 Java 应用程序访

问关系数据,则可利用 JDBC 调用进行访问。

本章并不深入讲解 JDBC 数据库接口,而是提供一些简单示例来介绍 JDBC,并阐释如何在客户端和数据库中使用 JDBC。

这些示例说明在 Adaptive Server Anywhere 中使用 JDBC 时的一些独特

功能。有关 JDBC 编程的更多信息,请参阅讲解 JDBC 编程的书籍。

JDBC 和和和和 Adaptive Server Anywhere

在 Adaptive Server Anywhere 中使用 JDBC 的方式如下:

• 客户端的客户端的客户端的客户端的 JDBC Java 客户端应用程序可对 Adaptive Server Anywhere 发出 JDBC 调用。通过 JDBC 驱动程序建立连接。

SQL Anywhere Studio 包括两个 JDBC 驱动程序:用于纯 Java 应用

程序的 jConnect 驱动程序以及 JDBC-ODBC Bridge。

本章中的术语 " 客户端应用程序客户端应用程序客户端应用程序客户端应用程序 " 指用户计算机上运行的应用程

序和中层应用程序服务器上运行的逻辑。

• 数据库中的数据库中的数据库中的数据库中的 JDBC 数据库中安装的 Java 类可使用内部 JDBC 驱动程序进行 JDBC 调用,以此来访问和修改数据库中的数据。

JDBC 资源资源资源资源 • 必需的软件必需的软件必需的软件必需的软件 使用 Sybase jConnect 驱动程序需要 TCP/IP。

您的计算机上可能已有 Sybase jConnect 驱动程序,具体有无取决

于所安装的 Adaptive Server Anywhere。

有关 jConnect 驱动程序及其位置的更多信息,请参阅 ""jConnect 驱动程序文件 " 第 146 页 "。

• 示例源代码示例源代码示例源代码示例源代码 本章中示例的源代码位于 SQL Anywhere 目录下的 Samples\ASA\Java\JDBCExamples.java 文件中。

有关如何建立 Java 示例 (包括 JDBCExamples 类)的更多信息,

请参阅 "" 设置 Java 示例 " 第 90 页 "。

140

Page 155: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

选择选择选择选择 JDBC 驱动程序驱动程序驱动程序驱动程序

为 Adaptive Server Anywhere 提供两个 JDBC 驱动程序:

• jConnect 此驱动程序是 100% 的 Java 驱动程序。它使用 TDS 客户 / 服务器协议与 Adaptive Server Anywhere 进行通信。

• JDBC-ODBC Bridge 此驱动程序使用 Command Sequence 客户 /服务器协议与 Adaptive Server Anywhere 进行通信。它的行为与 ODBC、嵌入式 SQL 和 OLE DB 应用程序是一致的。 .

在选择使用哪个驱动程序时,可能需要考虑下列因素:

• 特性特性特性特性 这两个驱动程序都兼容 JDK 2。 JDBC-ODBC Bridge 提供完

全可滚动的游标, jConnect 则不能。

• 纯纯纯纯 Java jConnect 驱动程序是纯 Java 解决方案。 JDBC-ODBC Bridge 需要 Adaptive Server Anywhere ODBC 驱动程序,它不是纯 Java 解决方案。

• 性能性能性能性能 在多数情况下, JDBC-ODBC Bridge 所提供的性能要比 jConnect 驱动程序好一些。

• 兼容性兼容性兼容性兼容性 jConnect 驱动程序使用的 TDS 协议可与 Adaptive Server Enterprise 共享。该驱动程序的行为的某些方面受此协议的控制,

并被配置为与 Adaptive Server Enterprise 兼容。

这两种驱动程序都可用于 Windows 95/98/Me 和 Windows NT/2000/XP,以及受支持的 UNIX 和 Linux 操作系统。它们不能用于 NetWare 或 Windows CE。

JDBC 程序结构程序结构程序结构程序结构

JDBC 应用程序中通常会发生以下一事件序列:

1. 创建连接对象创建连接对象创建连接对象创建连接对象 调用 DriverManager 类的 getConnection 类方法即可

创建 Connection 对象并与数据库建立连接。

2. 生成语句对象生成语句对象生成语句对象生成语句对象 Connection 对象生成 Statement 对象。

141

Page 156: Adaptive Server Anywhere

JDBC 概述

3. 传递传递传递传递 SQL 语句语句语句语句 在数据库环境内部执行的 SQL 语句传递到 Statement 对象。如果语句是一个查询,则此操作会返回 ResultSet 对象。

ResultSet 对象包含 SQL 语句返回的数据,但一次只显示一行 (与

游标的工作方式类似)。

4. 遍历结果集的行遍历结果集的行遍历结果集的行遍历结果集的行 ResultSet 对象的 next 方法可执行两种操作:

• 当前行 (通过 ResultSet 对象显示的结果集内的行)前进一

行。

• 返回布尔值 (true/false),指示要前进到的目标行是否真正存

在。

5. 为每行检索值为每行检索值为每行检索值为每行检索值 识别 ResultSet 对象中每一列的名称或位置,由此

检索每一列的值。 getDate 方法用于获取当前行中某列的值。

Java 对象可使用 JDBC 对象与数据库交互作用并获取数据供自己使用,

例如,获取数据后加以操纵或将其用在其它查询中。

数据库功能中的数据库功能中的数据库功能中的数据库功能中的 JDBC

您可从数据库中的 Java 使用哪个版本的 JDBC?这是由数据库设置中指

定要使用的 JDK 版本决定的。

• 如果数据库是用 JDK 1.2 或 JDK 1.3 初始化的,则可使用 JDBC 2.0 API。

有关将数据库升级到 JDK 1.2 或 JDK 1.3 的信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > ALTER DATABASE 语句 " 或 "ASA 数据库管理指南 > 数据库管理实用程序 > 使用 dbupgrad 实用程序升

级数据库 "。

• 如果数据库是用 JDK 1.1 初始化的,则可使用 JDBC 1.2 功能。适

用于 JDK 1.1 的内部 JDBC 驱动程序 (asajdbc) 使您能从服务器端的 Java 应用程序使用 JDBC 2.0 的某些功能,但未提供完整的 JDBC 2.0 支持。

有关更多信息,请参阅 "" 从 JDK 1.1 数据库使用 JDBC 2.0 功能 " 第 143 页 "。

142

Page 157: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

从从从从 JDK 1.1 数据库使用数据库使用数据库使用数据库使用 JDBC 2.0 功能功能功能功能

本节说明如何从那些使用 JDK 1.1 支持初始化的数据库访问 JDBC 2.0 功能。对于多数用途,更好的解决方案是将数据库中的 Java 版本升级到 1.3。

对于用 JDK 1.1 支持初始化的数据库, sybase.sql.ASA 包中包含一些功

能,这些功能属于 JDBC 2.0 的一部分。为了使用这些 JDBC 2.0 功能,

您必须将 JDBC 对象转换为 sybase.sql.ASA 包(而非 java.sql 包)中的

相应类。声明为 java.sql 的类仅限于 JDBC 1.2 功能。

sybase.sql.ASA 中的类如下所示:

以下函数为 prepared 语句提供一个 ResultSetMetaData 对象,无需 ResultSet,也不用执行该语句。此函数不是 JDBC 1.2 标准的一部分。

ResultSetMetaData sybase.sql.ASA.SAPreparedStatement.describe()

以下代码读取结果集中的前一行, JDBC 1.2 不支持此功能:

import java.sql.*;import sybase.sql.asa.*;ResultSet rs;// more code here( ( sybase.sql.asa.SAResultSet)rs ).previous();

JDBC 类类类类 Sybase 内部驱动程序类内部驱动程序类内部驱动程序类内部驱动程序类

java.sql.Connection sybase.sql.ASA.SAConnection

java.sql.Statement sybase.sql.ASA.SAStatement

java.sql.PreparedStatement sybase.sql.ASA.SAPreparedStatement

java.sql.CallableStatement sybase.sql.ASA.SACallableStatement

java.sql.ResultSetMetaData sybase.sql.ASA.SAResultSetMetaData

java.sql.ResultSet sybase.sql.SAResultSet

java.sql.DatabaseMetaData sybase.sql.SADatabaseMetaData

143

Page 158: Adaptive Server Anywhere

JDBC 概述

JDBC 2.0 限制限制限制限制 以下类是 JDBC 2.0 核心接口的一部分,但 sybase.sql.ASA 包中没有这

些类:

• java.sql.Blob

• java.sql.Clob

• java.sql.Ref

• java.sql.Struct

• java.sql.Array

• java.sql.Map

sybase.sql.ASA 包中没有以下 JDBC 2.0 核心函数:

sybase.sql.ASA 中的中的中的中的

类类类类缺少的函数缺少的函数缺少的函数缺少的函数

SAConnection java.util.Map getTypeMap()void setTypeMap( java.util.Map map )

SAPreparedStatement void setRef( int pidx, java.sql.Ref r )void setBlob( int pidx, java.sql.Blob b )void setClob( int pidx, java.sql.Clob c )void setArray( int pidx, java.sql.Array a )

SACallableStatement Object getObject( pidx, java.util.Map map )java.sql.Ref getRef( int pidx )java.sql.Blob getBlob( int pidx )java.sql.Clob getClob( int pidx )java.sql.Array getArray( int pidx )

144

Page 159: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

客户端与服务器端客户端与服务器端客户端与服务器端客户端与服务器端 JDBC 连接的区别连接的区别连接的区别连接的区别

客户端 JDBC 与数据库服务器中的 JDBC 之间的区别是它们与数据库环

境建立连接的方式不同。

• 客户端客户端客户端客户端 在客户端 JDBC 中,建立连接需要 Sybase jConnect JDBC 驱动程序或 Adaptive Server Anywhere JDBC-ODBC Bridge。将参

数传递给 DriverManager.getConnection 就建立了连接。从客户端

应用程序的角度看,数据库环境是外部应用程序。

• 服务器端服务器端服务器端服务器端 在数据库服务器中使用 JDBC 时,连接已经存在。

jdbc:default:connection 的值传递到 DriverManager.getConnection,从而使 JDBC 应用程序能在当前用

户连接中工作。这是一个快速、有效而安全的操作,因为客户端应用程序已通过了数据库安全检查建立了连接。用户 ID 和口令一

经提供,便不需要再次提供。内部 JDBC 驱动程序只能连接到当

前连接的数据库。

您可以用这样一种方式编写 JDBC 类:使用一个条件语句构造 URL,让 JDBC 类既能在客户端运行,又能在服务器端运行。外部连接需要计算

机名称和端口号,而内部连接需要 jdbc:default:connection。

SAResultSet Object getObject( int cidx, java.util.Map map )java.sql.Ref getRef( int cidx )java.sql.Blob getBlob( int cidx )java.sql.Clob getClob( int cidx )java.sql.Array getArray( int cidx )Object getObject( String cName, java.util.Map map )java.sql.Ref getRef( String cName )java.sql.Blob getBlob( String cName )java.sql.Clob getClob( String cName )java.sql.Array getArray( String cName )

sybase.sql.ASA 中的中的中的中的

类类类类缺少的函数缺少的函数缺少的函数缺少的函数

145

Page 160: Adaptive Server Anywhere

使用 jConnect JDBC 驱动程序

使用使用使用使用 jConnect JDBC 驱动程序驱动程序驱动程序驱动程序

如果希望从客户端应用程序或小程序使用 JDBC,必须让 jConnect JDBC 驱动程序连接到 Adaptive Server Anywhere 数据库。

SQL Anywhere Studio 中包含 jConnect。如果您得到的 Adaptive Server Anywhere 是另一软件包中的一部分,那么,其中可能会包括 jConnect,但也可能不包括。要从客户端应用程序使用 JDBC,就必须有 jConnect。在数据库中使用 JDBC 不需要 jConnect。

jConnect 驱动程序文件驱动程序文件驱动程序文件驱动程序文件

jConnect JDBC 驱动程序安装在 Sybase\Shared 目录下的一组目录中。

提供的 jConnect 有两个版本:

• jConnect 4.5 此版本的 jConnect 用于开发 JDK 1.1 应用程序,它

安装于 Sybase\Shared\jConnect-4_5 目录下。

jConnect 4.5 是作为一组类提供的。

• jConnect 5.5 此版本的 jConnect 用于开发 JDK 1.2 或更高版本的

应用程序,它安装于 Sybase\Shared\jConnect-5_5 目录下。

jConnect 5.5 是作为名为 jconn2.jar 的 jar 文件提供的。

本章中的示例使用 jConnect 5.5。 jConnect 4.5 的用户必须做相应的代

换。

为为为为 jConnect 设置设置设置设置 CLASSPATH

为了让应用程序使用 jConnect, jConnect 类在编译时和运行时必须位于

类路径中,这样, Java 编译器和 Java 运行时才能找到必要的文件。

以下命令将 jConnect 5.5 驱动程序添加到现有的 CLASSPATH 环境变量

中,其中 path 是 Sybase\Shared 目录。

set classpath=%classpath%;path\jConnect-5_5\classes\jconn2.jar

以下命令将 jConnect 4.5 驱动程序添加到现有的 CLASSPATH 环境变量

中:

146

Page 161: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

set classpath=%classpath%;path\jConnect-4_5\classes

导入导入导入导入 jConnect 类类类类 jConnect 中的所有类都在 com.sybase 包中。

如果您使用的是 jConnect 5.5,应用程序必须访问 com.sybase.jdbc2.jdbc 中的类。您必须在每个源文件的开头导入这些

类:

import com.sybase.jdbc2.jdbc.*

如果您使用的是 jConnect 4.5,则所有类都在 com.sybase.jdbc 中。您必

须在每个源文件的开头导入这些类:

import com.sybase. jdbc.*

在数据库中安装在数据库中安装在数据库中安装在数据库中安装 jConnect 系统对象系统对象系统对象系统对象

如果要用 jConnect 访问系统表信息(数据库元数据),必须将 jConnect 系统对象添加到数据库。

缺省情况下, jConnect 系统对象会被添加到任何新数据库中。您可以选

择在创建或升级数据库时将 jConnect 对象添加到数据库,也可以选择稍

后再添加。

您可以从 Sybase Central 或 Interactive SQL 安装 jConnect 系统对象。

❖ 向数据库添加向数据库添加向数据库添加向数据库添加 jConnect 系统对象系统对象系统对象系统对象 ( Sybase Central )::::

1 以具有 DBA 权限的用户身份从 Sybase Central 连接到数据库。

2 在 Sybase Central 的左窗格中,用右键单击数据库图标,然后从

弹出式菜单中选择 " 重新安装 jConnect 元数据支持 "。

❖ 向数据库添加向数据库添加向数据库添加向数据库添加 jConnect 系统对象系统对象系统对象系统对象 ( Interactive SQL )::::

• 以具有 DBA 权限的用户身份从 Interactive SQL 连接到数据库,

然后在 "SQL 语句 " 窗格中输入以下命令:

read path\scripts\jcatalog.sql

147

Page 162: Adaptive Server Anywhere

使用 jConnect JDBC 驱动程序

其中 path 是 SQL Anywhere 目录。

提示提示提示提示您也可使用命令提示符向数据库添加 jConnect 系统对象。在命令提示符

下键入:

dbisql -c "uid=user;pwd=pwd" path\scripts\jcatalog.sql

其中 user 和 pwd 标识具有 DBA 权限的用户, path 是 SQL Anywhere 目录。

装载装载装载装载 jConnect 驱动程序驱动程序驱动程序驱动程序

在应用程序中使用 jConnect 之前,需要先输入以下语句来装载驱动程

序:

Class.forName("com.sybase.jdbc2.jdbc.SybDriver").newInstance();

使用 newInstance 方法能解决某些浏览器中的问题。

提供服务器的提供服务器的提供服务器的提供服务器的 URL

要通过 jConnect 连接到数据库,您需要提供数据库的 " 统一资源定位器

"(URL)。"" 使用 jConnect 从 JDBC 客户端应用程序建立连接 " 第 153 页 "一节中提供了以下示例:

StringBuffer temp = new StringBuffer();// Use the jConnect driver...temp.append("jdbc:sybase:Tds:");// to connect to the supplied machine name...temp.append(_coninfo);// on the default port number for ASA...temp.append(":2638");// and connect.System.out.println(temp.toString());conn = DriverManager.getConnection(temp.toString() , _props );

完整的 URL 如下:

148

Page 163: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

jdbc:sybase:Tds:machine-name:port-number

各组成部分如下:

• jdbc:sybase:Tds 使用 TDS 应用程序协议的 Sybase jConnect JDBC 驱动程序。

• machine-name 运行服务器的计算机的 IP 地址或名称。如果要在

同一计算机内建立连接,可使用 localhost,表示当前计算机。

• port number 数据库服务器监听的端口号。分配给 Adaptive Server Anywhere 的端口号是 2638,除非有特殊原因不能使用该端

口号,否则请使用该端口号。

连接字符串长度必须小于 253 个字符。

指定服务器上的数据库指定服务器上的数据库指定服务器上的数据库指定服务器上的数据库

每个 Adaptive Server Anywhere 服务器都可以一次装载一个或多个数据

库。前面所述的 URL 指定服务器,但不指定数据库。尝试连接的数据

库是服务器上的缺省数据库。

您可以通过下列任一方式提供 URL 的扩展形式,由此而指定特定数据

库。

使用使用使用使用 ServiceName 参数参数参数参数

jdbc:sybase:Tds:machine-name:port-number?ServiceName=DBN

使用问号,后面跟随一系列赋值,这是向 URL 提供参数的标准方式。

servicename 是否大写并不重要,但 = 号两边不能有空格。 DBN 参数是

数据库名称。

使用使用使用使用 RemotePWD 参数参数参数参数

另一更常用的方法可用来提供其它连接参数,如数据库名或数据库文件,这种方法就是使用 RemotePWD 字段。您可用 setRemotePassword() 方法将 RemotePWD 设置成一个 " 属性 " 字段。

下面的示例代码说明了如何使用该字段。

149

Page 164: Adaptive Server Anywhere

使用 jConnect JDBC 驱动程序

sybDrvr = (SybDriver)Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" ).newInstance();

props = new Properties();props.put( "User", "DBA" );props.put( "Password", "SQL" );sybDrvr.setRemotePassword(

null, "dbf=asademo.db", props );Connection con = DriverManager.getConnection(

"jdbc:sybase:Tds:localhost", props );

利用数据库文件参数 DBF,您可使用 jConnect 启动服务器上的数据库。

缺省情况下,数据库启动时的设置为 autostop=YES。如果指定 utility_db 的 DBF 或 DBN, utility 数据库将自动启动。

有关 utility 数据库的更多信息,请参阅 "ASA 数据库管理指南 > 使用数

据库文件 > 使用 utility 数据库 "。

用于用于用于用于 jConnect 连接的数据库选项集连接的数据库选项集连接的数据库选项集连接的数据库选项集

应用程序使用 jConnect 驱动程序连接数据库时,将调用两个存储过程:

1. sp_tsql_environment 将一些数据库选项设置为与 Adaptive Server Enterprise 行为兼容。

2. 然后调用 spt_mda 过程,并设置其它选项。特别是, spt_mda 过程要

确定 QUOTED_IDENTIFIER 设置。要更改缺省行为,您必须修改 spt_mda 过程。

150

Page 165: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

使用使用使用使用 JDBC-ODBC Bridge

JDBC-ODBC Bridge 提供 JDBC 驱动程序,该程序与纯 Java jConnect JDBC 驱动程序相比有一些性能优势和特性优点,但它不是纯 Java 解决

方案。

有关选择使用哪一个 JDBC 驱动程序的信息,请参阅 "" 选择 JDBC 驱动

程序 " 第 141 页 "。

所需文件所需文件所需文件所需文件 JDBC-ODBC Bridge 的 Java 组件包括在 jodbc.jar 文件中,该文件安

装在 SQL Anywhere 的 Java 子目录中。对于 Windows,本机组件是 dbjodbc8.dll,它位于 SQL Anywhere 的 win32 子目录中。对于 UNIX 和 Linux,本机组件是 dbjodbc8.so。该组件必须位于系统路径中。当

部署使用该驱动程序的应用程序时,必须同时部署 ODBC 驱动程序文

件。

建立连接建立连接建立连接建立连接 下列代码说明如何使用 JDBC-ODBC Bridge 建立连接:

String driver, url;Connection conn;driver="ianywhere.ml.jdbcodbc.IDriver";url = "jdbc:odbc:dsn=ASA 8.0 Sample";Class.forName( driver );conn = DriverManager.getConnection( url );

有关此代码的注意事项如下:

• 由于使用了 Class.forName 加载类,所以不必使用 import 语句导入

包含 JDBC-ODBC Bridge 的包。

• 在运行应用程序时, jodbc.jar 必须位于类路径中。

• URL 包含 jdbc:odbc:,后跟一个标准的 ODBC 连接字符串。该连

接字符串通常是 ODBC 数据源,但除了该数据源以外,您还可以

使用分号分隔的明确单个连接参数辅之或代替该数据源。有关可在连接字符串中使用的参数的更多信息,请参阅 "ASA 数据库管

理指南 > 连接到数据库 > 连接参数 "。

如果不使用数据源,则必须指定要使用的 ODBC 驱动程序,方法

是在连接字符串中包括该驱动程序参数:

151

Page 166: Adaptive Server Anywhere

使用 JDBC-ODBC Bridge

url = "jdbc:odbc:";url += "driver=Adaptive Server Anywhere 8.0;...";

字符集字符集字符集字符集 在 UNIX 上, JDBC-ODBC Bridge 不 使用 ODBC Unicode 捆绑或调用,

并且不进行字符转换。通过 Bridge 发送非 ASCII 数据将导致数据被损

坏。

在 Windows 上, JDBC-ODBC Bridge 要 使用 ODBC Unicode 捆绑和调

用,以进行字符集转换。

152

Page 167: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

建立建立建立建立 JDBC 连接连接连接连接

本节介绍那些用来从 Java 应用程序建立 JDBC 数据库连接的类。本节中

的示例在数据库中使用 jConnect (客户端)或 Java (服务器端)。有关

使用 JDBC-ODBC Bridge 建立连接的信息,请参阅 "" 使用 JDBC-ODBC Bridge" 第 151 页 "。

使用使用使用使用 jConnect 从从从从 JDBC 客户端应用程序建立连接客户端应用程序建立连接客户端应用程序建立连接客户端应用程序建立连接

如果希望从 JDBC 应用程序访问数据库系统表 (数据库元数据),必须

向数据库添加一组 jConnect 系统对象。内部 JDBC 驱动程序类和 jConnect 共享数据库元数据支持的存储过程。这些过程会缺省安装到所

有数据库。 dbinit -i 选项会阻止此安装。

有关向数据库添加 jConnect 系统对象的更多信息,请参阅 "" 使用 jConnect JDBC 驱动程序 " 第 146 页 "。

以下完整的 Java 应用程序是一个命令行应用程序,它连接到正在运行

的数据库,在命令行显示一组信息,然后结束。

对于任何 JDBC 应用程序,要使用数据库数据,第一步都必须建立连

接。

该示例中所示的外部连接是常规的客户 / 服务器连接。有关从数据库服

务器内部运行的 Java 类创建内部连接的信息,请参阅 "" 从服务器端的 JDBC 类建立连接 " 第 157 页 "。

外部连接示例代码外部连接示例代码外部连接示例代码外部连接示例代码

以下是用来建立连接的方法的源代码。该源代码位于 JDBCExamples.java 文件的 main 和 ASAConnect 方法中,此文件在 SQL Anywhere 目录的 Samples\ASA\Java 目录下:

import java.sql.*; // JDBCimport com.sybase.jdbc2.jdbc.*; // Sybase jConnectimport java.util.Properties; // Propertiesimport sybase.sql.*; // Sybase utilitiesimport asademo.*; // Example classespublic class JDBCExamples{

153

Page 168: Adaptive Server Anywhere

建立 JDBC 连接

private static Connection conn; public static void main( String args[] ){ // Establish a connection conn = null; String machineName = ( args.length == 1 ? args[0] : "localhost" ); ASAConnect( "DBA", "SQL", machineName ); if( conn!=null ) { System.out.println( "Connection successful" ); }else{ System.out.println( "Connection failed" ); } try{ getObjectColumn(); getObjectColumnCastClass(); insertObject(); } catch( Exception e ){ System.out.println( "Error: " + e.getMessage() ); e.printStackTrace(); } }private static void ASAConnect( String userID,

String password, String machineName ) {

// Connect to an Adaptive Server Anywhere String coninfo = new String( machineName ); Properties props = new Properties(); props.put( "user", userID ); props.put( "password", password ); props.put("DYNAMIC_PREPARE", "true"); // Load jConnect try { Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" ).newInstance(); String dbURL = "jdbc:sybase:Tds:" + machineName + ":2638/?JCONNECT_VERSION=5"; System.out.println( dbURL ); conn = DriverManager.getConnection( dbURL , props ); }

154

Page 169: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

catch ( Exception e ) { System.out.println( "Error: " + e.getMessage() ); e.printStackTrace(); } }

外部连接示例如何工作外部连接示例如何工作外部连接示例如何工作外部连接示例如何工作

外部连接示例是 Java 命令行应用程序。

导入包导入包导入包导入包 该应用程序需要若干库,这些库在 JDBCExamples.java 的 先几行导

入:

• java.sql 包中包含所有 JDBC 应用程序需要的 Sun Microsystems JDBC 类。该包位于 Java 子目录下的 classes.zip 文件中。

• 使用 jConnect 建立连接的所有应用程序都需要从 com.sybase.jdbc2.jdbc 导入的 Sybase jConnect JDBC 驱动程序。

• 该应用程序使用 " 属性列表属性列表属性列表属性列表 "。处理属性列表需要 java.util.Properties 类。该类位于 Java 子目录下的 classes.zip 文件中。

• asademo 包中包含某些示例中用到的类。该包位于 Samples\ASA\Java\asademo.jar 文件中。

main 方法方法方法方法 每个 Java 应用程序都需要一个具有 main 方法的类, main 方法是在程

序启动时调用的方法。在此简单示例中, JDBCExamples.main 是应用

程序中的唯一外部可调用的方法。

JDBCExamples.main 方法执行以下任务:

1. 如果提供了计算机名称,则用计算机名称处理命令行参数。缺省情况下,计算机名称是适用于个人数据库服务器的 localhost。

2. 调用 ASAConnect 方法建立连接。

3. 执行将数据滚动到命令行的多个方法。

ASAConnect 方法方法方法方法 JDBCExamples.ASAConnect 方法执行以下任务:

1. 使用 Sybase jConnect 连接到缺省的运行数据库。

155

Page 170: Adaptive Server Anywhere

建立 JDBC 连接

• Class.forName 装载 jConnect。使用 newInstance 方法,它能

解决某些浏览器中的问题。

• StringBuffer 语句会根据命令行所提供的字符串和已有的计

算机名称建立连接字符串。

• DriverManager.getConnection 使用连接字符串建立连接。

2. 向调用方法返回控制。

运行外部连接示例运行外部连接示例运行外部连接示例运行外部连接示例

本节说明了如何运行外部连接示例。

❖ 创建并执行外部连接示例应用程序:创建并执行外部连接示例应用程序:创建并执行外部连接示例应用程序:创建并执行外部连接示例应用程序:

1 打开命令提示。

2 更改为 SQL Anywhere 目录。

3 更改为 Samples\ASA\Java 子目录。

4 确保数据库已装载到运行 TCP/IP 的数据库服务器上。您可使用

以下命令 (从 Samples\ASA\Java 子目录)在本地计算机上

启动此类服务器:

start dbeng8 ..\..\..\asademo

5 在命令提示符下输入以下内容,运行该示例:

java JDBCExamples

如果希望对另一计算机上运行的服务器尝试此命令,必须输入该计算机的正确名称。缺省名称为 localhost,它是当前计算机名,它是当前计算机名,它是当前计算机名,它是当前计算机名

称的别名。称的别名。称的别名。称的别名。

6 确认命令提示符下出现连接 URL 和连接成功信息。

如果连接尝试失败,则显示的是错误消息。请确认是否已执行了所需的全部步骤。请检查 CLASSPATH 是否正确。不正确的 CLASSPATH 将导致无法找到类。

156

Page 171: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

有关使用 jConnect 的更多信息,请参阅 "" 使用 jConnect JDBC 驱动程序

" 第 146 页 " 和 jConnect 的联机文档。

从服务器端的从服务器端的从服务器端的从服务器端的 JDBC 类建立连接类建立连接类建立连接类建立连接

JDBC 中的 SQL 语句是使用 Connection 对象的 createStatement 方法建

立的。即使是在服务器内部运行的类,也需要建立连接以创建 Connection 对象。

从服务器端的 JDBC 类建立连接比建立外部连接更为直接。因为已连接

的用户将执行服务器端的类,而该类只需使用当前连接。

服务器端连接的示例代码服务器端连接的示例代码服务器端连接的示例代码服务器端连接的示例代码

下面是该示例的源代码。它位于 SQL Anywhere 目录下 Samples\ASA\Java\JDBCExamples.java 的 InternalConnect 方法中:

public static void InternalConnect() { try { conn = DriverManager.getConnection("jdbc:default:connection"); System.out.println("Hello World"); } catch ( Exception e ) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); } }}

服务器端连接示例如何工作服务器端连接示例如何工作服务器端连接示例如何工作服务器端连接示例如何工作

在此简单示例中, InternalConnect() 是应用程序中所用的唯一方法。

该应用程序只需要在 JDBCExamples.java 类的第一行导入一个库 (JDBC)。其它库供外部连接使用。名为 java.sql 的包中包含 JDBC 类。

InternalConnect() 方法执行以下任务:

157

Page 172: Adaptive Server Anywhere

建立 JDBC 连接

1. 使用当前连接与缺省的运行数据库建立连接:

• DriverManager.getConnection 使用 jdbc:default:connection 的连接字符串建立连接。

2. 在当前标准输出 (服务器窗口)中显示 Hello World,

System.out.println 执行这一显示任务。

3. 如果尝试连接时出现错误,服务器窗口将显示一条错误消息,同时显示出现错误的位置。

try 和 catch 指令提供了处理错误的框架。

4. 终止该类。

运行服务器端连接示例运行服务器端连接示例运行服务器端连接示例运行服务器端连接示例

本节说明了如何运行服务器端连接示例。

❖ 创建并执行内部连接示例应用程序:创建并执行内部连接示例应用程序:创建并执行内部连接示例应用程序:创建并执行内部连接示例应用程序:

1 如果尚未编译 JDBCExamples.java 文件,先编译该文件。如

果您使用的是 JDK,可在命令提示符下从 Samples\ASA\Java 目录执行以下任务:

javac JDBCExamples.java

2 启动使用示例数据库的数据库服务器。您可以在本地计算机上使用以下命令 (从 Samples\ASA\Java 子目录)启动该服务

器:

start dbeng8 ..\..\..\asademo

在这种情况下,由于未使用 jConnect,因此可以不用 TCP/IP 网络协议。

3 在示例数据库中安装类。连接到示例数据库后,即可使用以下命令从 Interactive SQL 进行安装:

INSTALL JAVA NEWFROM FILE 'path\Samples\ASA\Java\JDBCExamples.class'

158

Page 173: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

其中 path 是安装目录的路径。

您也可使用 Sybase Central 安装此类。在连接到示例数据库时,

打开 Java Objects 文件夹,双击 " 添加 Java 类 ",然后按向导中

的说明进行操作。

4 您现在可调用此类的 InternalConnect 方法,就像调用存储过程

一样:

CALL JDBCExamples>>InternalConnect()

第一次在会话中调用 Java 类时,必须装载内部 Java 虚拟机。这

可能需要几秒钟。

5 确认服务器屏幕上是否出现 Hello World 这一消息。

有关有关有关有关 JDBC 连接的几点说明连接的几点说明连接的几点说明连接的几点说明

• 自动提交行为自动提交行为自动提交行为自动提交行为 JDBC 规范要求在每个数据修改语句后缺省执行 COMMIT。当前,服务器端 JDBC 行为是提交。您可使用以下语

句控制这一行为:

conn.setAutoCommit( false ) ;

其中 conn 是当前的连接对象。

• 连接缺省值连接缺省值连接缺省值连接缺省值 从服务器端的 JDBC 对 getConnection( "jdbc:default:connection" ) 的所有调用中,只有第一个调用在创

建新连接时使用缺省值。后续调用返回当前连接的包装,所有连接属性均保持不变。如果在初始连接中将 AutoCommit 设为 OFF,同一 Java 代码中,任何后续 getConnection 调用所返回的连接中

的 AutoCommit 均设置为 OFF。

您可能希望确保关闭连接会将连接属性重置为缺省值,这样,所获得的后续连接就会采用标准的 JDBC 值。以下代码示范可实现

这一点:

159

Page 174: Adaptive Server Anywhere

建立 JDBC 连接

Connection conn = DriverManager.getConnection(");boolean oldAutoCommit = conn.getAutoCommit();try { // do code here}finally { conn.setAutoCommit( oldAutoCommit );}

此处的讨论不仅适用于 AutoCommit,也适用于 TransactionIsolation 和 isReadOnly 等其它连接属性。

160

Page 175: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

使用使用使用使用 JDBC 访问数据访问数据访问数据访问数据

在数据库中保存某些类或全部类的 Java 应用程序大大优于传统的 SQL 存储过程。不过,在入门阶段, 好并行使用 SQL 存储过程来证实 JDBC 的功能,这样或许会有所帮助。在下面的示例中,我们编写了向 Department 表中插入行的 Java 类。

与其它接口一样, JDBC 中的 SQL 语句要么为 " 静态静态静态静态 ",要么为

" 动态动态动态动态 "。静态 SQL 语句在 Java 应用程序中构造,然后会发送到数据库。

数据库服务器会分析该语句,选择执行计划,然后执行该语句。语法分析与选择执行计划统称为 " 准备准备准备准备 " 语句。

如果某条类似的语句必须被执行多次 (例如,向一个表中插入多次),使用静态 SQL 会带来很大的开销,因为每次都必须执行准备步骤。

相对而言,动态 SQL 语句包含占位符。只需用这些占位符准备一次语

句,就可以多次执行语句,省去了额外的准备开销。

本节使用静态 SQL。动态 SQL 将在后面一节讨论。

准备示例准备示例准备示例准备示例

本节说明了如何为本章其余部分的示例做准备。

示例代码示例代码示例代码示例代码 本节中的代码段取自完整类 Samples\ASA\Java\JDBCExamples.java。

❖ 安装安装安装安装 JDBCExamples 类:类:类:类:

• 如果尚未安装 JDBCExamples 类,请在示例数据库中安装 JDBCExamples.class 文件。从 Interactive SQL 连接到示例数

据库后,请在 "SQL 语句 " 窗格中输入以下命令:

INSTALL JAVA NEWFROM FILE 'path\Samples\ASA\Java\JDBCExamples.class'

其中 path 是安装目录的路径。

161

Page 176: Adaptive Server Anywhere

使用 JDBC 访问数据

您也可使用 Sybase Central 安装此类。在连接着示例数据库时,

打开 Java Objects 文件夹,双击 " 添加 Java 类 ",然后按向导中

的说明进行操作。

使用使用使用使用 JDBC 执行插入、更新和删除执行插入、更新和删除执行插入、更新和删除执行插入、更新和删除

Statement 对象执行静态 SQL 语句。您可使用 Statement 对象的 executeUpdate 方法执行 INSERT、 UPDATE 和 DELETE 等 SQL 语句,

这些语句不返回结果集。诸如 CREATE TABLE 的语句及其它数据定义

语句也可通过 executeUpdate 来执行。

以下代码段说明了 JDBC 如何执行 INSERT 语句。它使用名为 conn 的" 连接 " 对象中所包含的内部连接。使用 JDBC 从外部应用程序插入值的

代码需要使用另一不同连接,但其它方面均保持不变。

public static void InsertFixed() { // returns current connection conn = DriverManager.getConnection("jdbc:default:connection"); // Disable autocommit conn.setAutoCommit( false ); Statement stmt = conn.createStatement(); Integer IRows = new Integer( stmt.executeUpdate

("INSERT INTO Department (dept_id, dept_name )" + "VALUES (201, 'Eastern Sales')" ) );

// Print the number of rows updated System.out.println(IRows.toString() + " row inserted" ); }

可用源代码可用源代码可用源代码可用源代码此代码段是 JDBCExamples 类的 InsertFixed 方法的一部分,该类位于

安装目录的 Samples\ASA\Java 子目录下。

注意注意注意注意 • setAutoCommit 方法关闭自动提交行为,因此只有执行显式 COMMIT 指令,才会提交更改。

162

Page 177: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

• executeUpdate 方法返回一个整数,该数字反映受操作影响的行

数。在此情况下,成功的 INSERT 会返回值一 (1)。

• 整数返回类型转换为 Integer 对象。 Interger 类是基本 int 数据类型

的包装,它提供一些有用的方法,如 toString()。

• 整数 IRows 转换为要显示的字符串,输出将显示在服务器窗口

中。

❖ 运行运行运行运行 JDBC 的的的的 Insert 示例:示例:示例:示例:

1 以用户 ID DBA 的身份使用 Interactive SQL 连接到示例数据库。

2 确保已安装 JDBCExamples 类。它是与其它 Java 示例类一起安

装的。

有关配置 Java 示例类的更多信息,请参阅 "" 设置 Java 示例 " 第90 页 "。

3 按以下方式调用方法:

CALL JDBCExamples>>InsertFixed()

4 确认 department 表中已添加一行。

SELECT *FROM department

不提交 ID 为 201 的行。您可执行 ROLLBACK 语句以删除该

行。

在此示例中,您已看到了如何创建非常简单的 JDBC 类,我们将在它的

基础上接着介绍其它示例。

向向向向 Java 方法传递参数方法传递参数方法传递参数方法传递参数

我们可以展开 InsertFixed 方法,来说明如何将参数传递给 Java 方法。

以下方法使用在调用中传递给该方法的参数作为插入值:

163

Page 178: Adaptive Server Anywhere

使用 JDBC 访问数据

public static void InsertArguments( String id, String name) {

try { conn = DriverManager.getConnection( "jdbc:default:connection" );String sqlStr = "INSERT INTO Department "

+ " ( dept_id, dept_name )"+ " VALUES (" + id + ", '" + name + "')";

// Execute the statement Statement stmt = conn.createStatement(); Integer IRows = new Integer( stmt.executeUpdate( sqlStr.toString() ) ); // Print the number of rows updated System.out.println(IRows.toString() + " row inserted" ); } catch ( Exception e ) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); } }

注意注意注意注意 • 这两个参数是部门 ID (整数)和部门名称 (字符串)。由于两个

参数是 SQL 语句字符串的一部分,因此它们在此处都作为字符串

传递给方法。

• INSERT 是静态语句,除 SQL 自身外,它不带任何参数。

• 如果提供的参数数目或类型有错误,将出现 " 未找到过程 " 错误。

❖ 使用带参数的使用带参数的使用带参数的使用带参数的 Java 方法:方法:方法:方法:

1 如果尚未在示例数据库中安装 JDBCExamples.class 文件,请

安装该文件。

2 从 Interactive SQL 连接到示例数据库,然后输入以下命令:

call JDBCExamples>>InsertArguments( '203', 'Northern Sales' )

164

Page 179: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

3 检查 Department 表中是否已另外添加了一行:

SELECT *FROM Department

4 回退更改,使数据库保持原样:

ROLLBACK

使用使用使用使用 JDBC 的查询的查询的查询的查询

Statement 对象执行静态查询和不返回结果集的语句。对于查询,应使

用 Statement 对象的 executeQuery 方法。这将在 ResultSet 对象中返回

结果集。

以下代码段说明了如何在 JDBC 中处理查询。此代码段将产品的总库存

值放在名为 inventory 的变量中。产品名称包含在 String 变量 prodname 中。此示例可用作 JDBCExamples 类的 Query 方法。

此示例假定已建立了内部或外部连接,该连接包含在名为 conn 的连接

对象中。

public static int Query () {int max_price = 0; try{ conn = DriverManager.getConnection( "jdbc:default:connection" ); // Build the query String sqlStr = "SELECT id, unit_price "+ "FROM product" ; // Execute the statement Statement stmt = conn.createStatement(); ResultSet result = stmt.executeQuery( sqlStr ); while( result.next() ) {int price = result.getInt(2);System.out.println( "Price is " + price );if( price > max_price ) { max_price = price ;} } } catch( Exception e ) {

165

Page 180: Adaptive Server Anywhere

使用 JDBC 访问数据

System.out.println("Error: " + e.getMessage()); e.printStackTrace(); } return max_price; }

运行示例运行示例运行示例运行示例 在示例数据库中安装 JDBCExamples 类后,可以在 Interactive SQL 中使

用以下语句执行该方法:

CALL JDBCExamples>>Query()

注意注意注意注意 • 该查询选择名为 prodname 的所有产品的数量和单价。这些结果

返回到名为 result 的 ResultSet 对象中。

• 遍历结果集内的每一行。该遍历使用 next 方法。

• 使用 getInt 方法将每一行各列的值检索到整型变量中。 ResultSet 还有针对其它数据类型的方法,如 getString、 getDate 和 getBinaryString。

getInt 方法的参数是列的索引号,索引号是从 1 开始编排的。

根据 "ASA SQL 参考手册 > SQL 数据类型 > SQL 到 Java 的数据类

型转换 " 中的信息执行 SQL 到 Java 的数据类型转换。

• Adaptive Server Anywhere 支持双向滚动游标。不过, JDBC 只提

供 next 方法,相当于在结果集中向前滚动。

• 该方法向调用环境返回 max_price 的值,Interactive SQL 在 " 结果 "窗格的 " 结果 " 选项卡上显示该值。

使用使用使用使用 prepared 语句进行更有效的访问语句进行更有效的访问语句进行更有效的访问语句进行更有效的访问

如果使用 Statement 接口,则将分析每条发送到数据库的语句,生成访

问计划,然后执行该语句。实际执行语句前的步骤称为 " 准备准备准备准备 " 语句。

如果使用 PreparedStatement 接口,将会在性能方面获得一些益处。这

样您就可以使用占位符来准备语句,然后在执行语句时向占位符赋值。

使用 prepared 语句在执行多个类似操作 (如插入多行)时尤其有用。

166

Page 181: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

有关 prepared 语句的更多信息,请参阅 "" 准备语句 " 第 12 页 "。

示例示例示例示例 以下示例阐释了如何使用 PreparedStatement 接口,只不过插入单行并

未有效地利用 prepared 语句。

JDBCExamples 类的以下方法执行一个 prepared 语句:

public static void JInsertPrepared(int id, String name) try { conn = DriverManager.getConnection( "jdbc:default:connection"); // Build the INSERT statement // ? is a placeholder character String sqlStr = "INSERT INTO Department "

+ "( dept_id, dept_name ) "+ "VALUES ( ? , ? )" ;

// Prepare the statement PreparedStatement stmt = conn.prepareStatement( sqlStr ); stmt.setInt(1, id); stmt.setString(2, name ); Integer IRows = new Integer( stmt.executeUpdate() ); // Print the number of rows updated System.out.println(IRows.toString() + " row inserted" ); } catch ( Exception e ) { System.out.println("Error: " + e.getMessage()); e.printStackTrace(); } }

运行示例运行示例运行示例运行示例 在示例数据库中安装 JDBCExamples 类后,可输入以下语句执行此示

例:

call JDBCExamples>>InsertPrepared( 202, 'Eastern Sales' )

字符串参数括在单引号中,这是适用于 SQL 的规范。如果从 Java 应用

程序调用此方法,则应使用双引号来分隔该字符串。

167

Page 182: Adaptive Server Anywhere

使用 JDBC 访问数据

插入和检索对象插入和检索对象插入和检索对象插入和检索对象

JDBC 作为关系数据库的接口,其设计目的是为了检索和操纵传统的 SQL 数据类型。 Adaptive Server Anywhere 也以 Java 类的形式提供了抽

象数据类型。使用 JDBC 来访问这些 Java 类的方式取决于您是要插入对

象还是要检索对象。

有关获取和设置整个对象的更多信息,请参阅 "" 创建分布式应用程序 " 第 170 页 "。

检索对象检索对象检索对象检索对象

您可以通过以下方式检索对象、对象字段及对象方法:

• 访问方法和字段访问方法和字段访问方法和字段访问方法和字段 Java 方法和字段可以包含在查询的选择列表中。

这样,方法或字段会显示为结果集中的列,通过标准的 ResultSet 方法 (如 getInt 或 getString)就能访问这些列。

• 检索对象检索对象检索对象检索对象 如果查询选择列表中包括了使用 Java 类数据类型的

列,您可以使用 ResultSet getObject 方法将对象检索到 Java 类中。然后,在 Java 类中访问该对象的方法和字段。

插入对象插入对象插入对象插入对象

您可从服务器端的 Java 类使用 JDBC setObject 方法将对象插入到数据

类型为 Java 类数据类型的列中。

您可使用 prepared 语句插入对象。例如,以下代码段将 MyJavaClass 类型的对象插入到表 T 的列中:

java.sql.PreparedStatement ps = conn.prepareStatement("insert T values( ? )" );ps.setObject( 1, new MyJavaClass() );ps.executeUpdate();

另一方法是建立保存对象的 SQL 变量,然后将该变量插入表中。

168

Page 183: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

其它其它其它其它 JDBC 注释注释注释注释

• 访问权限访问权限访问权限访问权限 与数据库中的所有 Java 类一样,包含 JDBC 语句的类

可由任何用户访问。没有等同于 GRANT EXECUTE 语句 (该语

句授予执行过程的权限)的语句,也无需用类所有者的名称限定类名称。

• 执行权限执行权限执行权限执行权限 执行 Java 类时需要使用执行这些类的连接的权限。此

行为与存储过程的行为不同,执行存储过程需要所有者权限。

169

Page 184: Adaptive Server Anywhere

创建分布式应用程序

创建分布式应用程序创建分布式应用程序创建分布式应用程序创建分布式应用程序

在 " 分布式应用程序分布式应用程序分布式应用程序分布式应用程序 " 中,部分应用程序逻辑在一台计算机上运行,另

外一部分在另一台计算机上运行。利用 Adaptive Server Anywhere,您可

创建分布式 Java 应用程序,让部分逻辑在数据库服务器中运行,另一

部分逻辑在客户端计算机上运行。

Adaptive Server Anywhere 能够与外部 Java 客户端交换 Java 对象。

让客户端应用程序从数据库检索 Java 对象是分布式应用程序中的关键

任务。本节说明如何完成此任务。

相关任务相关任务相关任务相关任务 在本章的其它部分,我们已经说明了如何检索与对象检索相关的多个任务,但不应将检索这些任务与检索对象本身相混淆。例如:

• ""查询 Java 对象 " 第 114页 " 说明如何将对象检索到 SQL 变量中。

它未解决将对象放入 Java 应用程序的问题。

• ""查询 Java 对象 " 第 114页 "还说明如何检索公共字段并返回 Java 方法的值。这也与将对象检索到 Java 应用程序中不同。

• " 插入和检索对象 " 第 168 页说明如何将对象检索到服务器端的 Java 类中。这也与将对象检索到客户端应用程序中不同。

分布式应用程序的要分布式应用程序的要分布式应用程序的要分布式应用程序的要求求求求

建立分布式应用程序涉及到多个任务。

❖ 建立分布式应用程序:建立分布式应用程序:建立分布式应用程序:建立分布式应用程序:

1 服务器中运行的所有类都必须实现 Serializable 接口。这非常简

单。

2 客户端应用程序必须导入类,这样才能在客户端重新构造对象。

3 使用 sybase.sql.ASAUtils.toByteArray 方法在服务器端序列化对

象。只有 Adaptive Server Anywhere 6.0.1 版和更早版本需要此步

骤。

170

Page 185: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

4 使用 sybase.sql.ASAUtils.fromByteArray 方法在客户端重新构

造对象。只有 Adaptive Server Anywhere 6.0.1 版和更早版本需要

此步骤。

以下各节对这些任务逐一进行说明。

实现实现实现实现 Serializable 接口接口接口接口

对象以 " 序列化序列化序列化序列化 " 的形式从服务器传递到客户端应用程序。这意味着每

行均包含以下信息:

• 版本标识符。

• 所存储类 (或子类)的标识符。

• 类中非静态、非瞬时字段的值。

• 其它开销信息。

为了让对象传送到客户端应用程序,对象必须实现 Serializable 接口。

好在该任务非常简单。

❖ 实现实现实现实现 Serializable 接口:接口:接口:接口:

• 将 implements java.io.Serializable 字样添加到类定义中。

例如, Samples\ASA\Java\asademo\Product.java 借助于以

下声明实现 Serializable 接口:

public class Product implements java.io.Serializable

实现 Serializable 接口就等于直接声明类可以被序列化。

Serializable 接口不包含任何方法和变量。序列化对象会将该对象转换为

字节流,这样它就可以保存到磁盘或发送到其它 Java 应用程序,然后

可以在磁盘或该 Java 应用程序中重新构建它或对它 " 反序列化反序列化反序列化反序列化 "。

171

Page 186: Adaptive Server Anywhere

创建分布式应用程序

数据库服务器中的序列化 Java 对象被发送到客户端应用程序并反序列

化后,各方面仍与其原始状态完全相同。不过,对象中的某些变量要么不需要被序列化,要么由于安全原因而不应被序列化。应使用关键字 transient 声明那些变量,如下面的变量声明中所示。

transient String password;

带有该变量的对象被反序列化后,总是包含其缺省值 null。

在类中添加 writeObject() 和 readObject() 方法即可完成自定义序列化。

有关序列化的更多信息,请参阅 Sun Microsystems 的 "Java 开发工具包 (JDK)"。

在客户端导入类在客户端导入类在客户端导入类在客户端导入类

在客户端,检索对象的任何类都必须具备对相应类定义的访问权限才能使用对象。如果要使用 Product 类 (它是 asademo 包的一部分),应

用程序中必须包括下面一行:

import asademo.*

CALSSPATH 中必须包括 asademo.jar 文件,这样才能找到此包。

分布式应用程序示例分布式应用程序示例分布式应用程序示例分布式应用程序示例

JDBCExamples.java 类包含说明分布式 Java 计算的三种方法。这些方

法都从 main 方法调用。在 "" 使用 jConnect 从 JDBC 客户端应用程序建

立连接 " 第 153 页 " 一节介绍的连接示例中调用了 main 方法,该方法也

是分布式应用程序的一个示例。

下面是 JDBCExamples 类中的 getObjectColumn 方法。

private static void getObjectColumn() throws Exception {// Return a result set from a column containing// Java objects asademo.ContactInfo ci; String name; String sComment ; if ( conn != null ) {

172

Page 187: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "SELECT JContactInfo FROM jdba.contact" ); while ( rs.next() ) { ci = ( asademo.ContactInfo )rs.getObject(1); System.out.println( "\n\tStreet: " + ci.street + "City: " + ci.city + "\n\tState: " + ci.state + "Phone: " + ci.phone + "\n" ); } } }

getObject 方法的使用方式与在内部 Java 中的使用方式相同。

旧方法旧方法旧方法旧方法

建议使用建议使用建议使用建议使用 getObject 和和和和 setObject软件的早期版本中需要进行显式序列化和反序列化,有了 getObject 和 setObject 方法,就不再需要了。本节为维护使用这些技术的代码的用

户介绍这一较旧的方法。

本节介绍其中一个示例如何工作。您可以自己研究其它示例的代码。

序列化和反序列化查序列化和反序列化查序列化和反序列化查序列化和反序列化查询结果询结果询结果询结果

下面是旧版本的 JDBCExamples 类的 serializeColumn 方法。

private static void serializeColumn() throws Exception { Statement stmt; ResultSet rs; byte arrayb[]; asademo.ContactInfo ci; String name; if ( conn != null ) { stmt = conn.createStatement(); rs = stmt.executeQuery( "SELECT sybase.sql.ASAUtils.toByteArray( JName.getName() ) AS Name, sybase.sql.ASAUtils.toByteArray( jdba.contact.JContactInfo )

173

Page 188: Adaptive Server Anywhere

创建分布式应用程序

FROM jdba.contact" ); while ( rs.next() ) { arrayb = rs.getBytes("Name"); name = ( String )sybase.sql.ASAUtils.fromByteArray( arrayb ); arrayb = rs.getBytes(2); ci = (asademo.ContactInfo)sybase.sql.ASAUtils.fromByteArray( arrayb ); System.out.println( "Name: " + name + "\n\tStreet: " + ci.street + "\n\tCity: " + ci.city + "\n\tState: " + ci.state + "\n\tPhone: " + ci.phone + "\n" ); } System.out.println( "\n\n" ); } }

下面是该方法的工作方式:

1. 调用方法时连接已存在。将检查连接对象,只要存在该对象,就执行代码。

2. 构造并执行 SQL 查询。该查询如下:

SELECTsybase.sql.ASAUtils.toByteArray( JName.getName() )AS Name,sybase.sql.ASAUtils.toByteArray( jdba.contact.JContactInfo ) FROM jdba.contact

该语句查询 jdba.contact 表。它从 JName 和 JContactInfo 列获取信

息。 sybase.sql.ASAUtils.toByteArray 函数不只是检查列本身或该

列的方法,而是将值转换为字节流,以使其能被序列化。

3. 客户端遍历结果集的行。每行中各列的值均被反序列化到对象中。

4. 从输出 (System.out.println) 中可看出:对象的字段和方法可以像在

它们的原始状态下一样使用。

174

Page 189: Adaptive Server Anywhere

第 5 章 使用 JDBC 访问数据

分布式应用程序的其它功能分布式应用程序的其它功能分布式应用程序的其它功能分布式应用程序的其它功能

JDBCExamples.java 中还有其它两种使用分布式计算的方法:

• serializeVariable 此方法创建由数据库服务器上的 SQL 变量引用

的本地 Java 对象,并将其传递回客户端应用程序。

• serializeColumnCastClass 此方法与 serializeColumn 方法类似,

但讲的是如何重新构造子类。被查询列 (product 表中的 JProd)的数据类型为 asademo.Product。某些行为 asademo.Hat,它是 Product 类的子类。相应的类会在客户端得以

重新构造。

175

Page 190: Adaptive Server Anywhere

创建分布式应用程序

176

Page 191: Adaptive Server Anywhere

第 6 章

嵌入式嵌入式嵌入式嵌入式 SQL 编程编程编程编程

关于本章关于本章关于本章关于本章 本章说明如何使用 Adaptive Server Anywhere 的嵌入式 SQL 编程接口。

177

Page 192: Adaptive Server Anywhere

简介

简介简介简介简介

" 嵌入式 SQL" 是用于 C 和 C++ 编程语言的数据库编程接口。它由混杂

在(嵌入于) C 或 C++ 源代码中的 SQL 语句组成。这些 SQL 语句先由

SQL 预处理器预处理器预处理器预处理器转换为 C 或 C++ 源代码,然后您再进行编译。

在运行时,嵌入式 SQL 应用程序使用 Adaptive Server Anywhere" 接口库接口库接口库接口库

" 与数据库服务器进行通信。在大多数平台上,接口库是一个动态链接

库 (DLL) 或共享库。

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

• 在 UNIX 操作系统上,接口库会是 libdblib8.so、libdblib8.sl 或 libdblib8.a(视操作系统而定)。

Adaptive Server Anywhere 提供了两种嵌入式 SQL。静态嵌入式 SQL 使用起来比较简单,但它不如动态嵌入式 SQL 灵活。在本章中将对这两

种嵌入式 SQL 进行讨论。

178

Page 193: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

开发过程概述开发过程概述开发过程概述开发过程概述

在对程序成功地进行预处理和编译后,就可以将它与 Adaptive Server Anywhere 接口库的 " 导入库导入库导入库导入库 " 链接在一起,以形成可执行文件。在运行

数据库时,这个可执行文件使用 Adaptive Server Anywhere DLL 与数据

库交互作用。在对程序进行预处理时,不必运行数据库。

对于 Windows, Watcom C/C++、 Microsoft Visual C++ 和 Borland C++ 各自有单独的导入库。

C 源代码

SQL预处理器

C 编译器

链接器

自定义应用程序

DLL

DLL 导入库

数据库

179

Page 194: Adaptive Server Anywhere

简介

使用导入库是调用 DLL 中函数的应用程序的标准开发方法。 Adaptive Server Anywhere 还提供了另外一种方法来避免使用导入库 (建议使用

此方法)。有关更多信息,请参阅 " 动态装载接口库 " 第 183 页。

运行运行运行运行 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 预处理器 " 第 247 页。

支持的编译器支持的编译器支持的编译器支持的编译器

C 语言 SQL 预处理器已经可以与下列编译器联合使用:

有关构建 NetWare NLM 的说明,请参阅 " 构建 NetWare 可装载模块 " 第185 页。

操作系统操作系统操作系统操作系统 编译器编译器编译器编译器 版本版本版本版本

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

180

Page 195: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

嵌入式嵌入式嵌入式嵌入式 SQL 头文件头文件头文件头文件

所有头文件都安装在您的 Adaptive Server Anywhere 安装目录的 h 子目

录中。

导入库导入库导入库导入库

所有导入库都安装在 Adaptive Server Anywhere 安装目录的操作系统子

目录下的 lib 子目录中。例如, Windows 导入库存储在 win32\lib 子目录中。

文件名文件名文件名文件名 说明说明说明说明

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 此头文件可确保正确地处理结构压缩。它支持 Watcom C/C++、 Microsoft Visual C++、 IBM Visual Age 和 Borland C/C++ 编译器。

pshpk2.h 此头文件可确保正确地处理结构压缩。它支持 Watcom C/C++、 Microsoft Visual C++、 IBM Visual Age 和 Borland C/C++ 编译器。

poppk.h 此头文件可确保正确地处理结构压缩。它支持 Watcom C/C++、 Microsoft Visual C++、 IBM Visual Age 和 Borland C/C++ 编译器。

181

Page 196: Adaptive Server Anywhere

简介

libdbtasks8 库由 libdblib8 库调用。有些编译器会自动定位 libdbtasks8,而对于其它编译器,则需要您显式指定它。

简单示例简单示例简单示例简单示例

下面是一个非常简单的嵌入式 SQL 程序示例。

#include <stdio.h>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:

操作系统操作系统操作系统操作系统 编译器编译器编译器编译器 导入库导入库导入库导入库

Windows Watcom C/C++ dblibtw.lib

Windows Microsoft Visual C++ dblibtm.lib

Windows CE Microsoft Visual C++ dblib8.lib

NetWare Watcom C/C++ dblib8.lib

Solaris (非线程应用程序) 所有编译器 libdblib8.so, libdbtasks8.so

Solaris (线程应用程序) 所有编译器 libdblib8_r.so, libdbtasks8_r.so

182

Page 197: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

printf( "update unsuccessful -- sqlcode = %ld.n",sqlca.sqlcode );

db_fini( &sqlca );return( -1 );

}

此示例连接到数据库,更新 195 号雇员的姓氏,提交更改,然后退出。

实际上 SQL 和 C 代码之间没有交互作用。在本示例中 C 代码仅用于控

制流。 WHENEVER 语句用于错误检查。错误处理 (此示例中的 GOTO)会在任何引起错误的 SQL 语句之后执行。

有关读取数据的说明,请参阅 " 读取数据 " 第 210 页。

嵌入式嵌入式嵌入式嵌入式 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 中的函数的应用程序的通常做法是,把应用程序链接到

包含所需函数定义的 " 导入库导入库导入库导入库 "。

183

Page 198: Adaptive Server Anywhere

简介

本节介绍了在开发 Adaptive Server Anywhere 应用程序时不使用导入库

的方法。使用安装目录的 src 子目录中的 esqldll.c 模块,可以动态

装载 Adaptive Server Anywhere 接口库,而不必针对导入库进行链接。

建议使用 esqldll.c,因为它更易于使用而且其定位接口 DLL 的能力

更强。

❖ 动态装载接口动态装载接口动态装载接口动态装载接口 DLL::::

1 您的程序必须调用 db_init_dll 才能装载 DLL,而且必须调用 db_fini_dll 才能释放 DLL。必须在调用数据库接口中的所有函

数之前调用 db_init_dll,而且在调用 db_fini_dll 之后不能调用

接口中的任何函数。

您还必须调用 db_init 和 db_fini 库函数。

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

件。

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

4 编译 esqldll.c。

5 将对象模块 esqldll.obj 与您的嵌入式 SQL 应用程序对象链

接在一起,而不是针对导入库进行链接。

示例示例示例示例 您可以在 SQL Anywhere 目录的 Samples\ASA\ESQLDynamicLoad 子目

录中找到一个示例程序,该程序说明如何动态装载接口库。源代码位于 Samples\ASA\ESQLDynamicLoad\sample.sqc 中。

宏宏宏宏 平台平台平台平台

_SQL_OS_WINNT 所有 Windows 操作系统

_SQL_OS_UNIX UNIX

_SQL_OS_NETWARE NetWare

184

Page 199: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

构建构建构建构建 NetWare 可装载模块可装载模块可装载模块可装载模块

您必须使用 Watcom C/C++ 编译器 10.6 版或 11.0 版将嵌入式 SQL 程序

编译为 NetWare 可装载模块 (NLM)。

❖ 创建嵌入式创建嵌入式创建嵌入式创建嵌入式 SQL NLM::::

1 在 Windows 上,使用以下命令对嵌入式 SQL 文件进行预处理:

sqlpp -o NETWARE srcfile.sqc

此指令可创建扩展名为 .c 的文件。

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

编译 file.c。

3 使用 Watcom 链接器 (使用以下选项)链接生成的目标文件:

FORMAT NOVELLMODULE dblib8OPTION CASEEXACTIMPORT @dblib8.impLIBRARY dblib8.lib

文件 dblib8.imp 和 dblib8.lib 随 Adaptive Server Anywhere 提供,它们位于 nlm\lib 目录中。 IMPORT 和 LIBRARY 行可

能需要完整路径。

185

Page 200: Adaptive Server Anywhere

示例嵌入式 SQL 程序

示例嵌入式示例嵌入式示例嵌入式示例嵌入式 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;对于 windowing 环境是 mainwin.c。

每个示例程序都提供了以下三个从主线调用的例程。

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

• WSQLEX_Process_Command :处理来自用户的命令,根据需

要操纵游标。

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

主线的功能是:

1. 调用 WSQLEX_Init 例程

2. 执行循环,从用户获取命令并调用 WSQL_Process_Command,直

到用户退出

3. 调用 WSQLEX_Finish 例程

连接到数据库是使用提供适当用户 ID 和口令的嵌入式 SQL CONNECT 命令完成的。

除了这些示例之外,您还可以找到作为 SQL Anywhere Studio 的一部

分、演示可用于特定平台的功能的其它程序和源文件。

186

Page 201: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

构建示例程序构建示例程序构建示例程序构建示例程序

用于构建示例程序的文件随示例代码提供。

• 对于由 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 目录中。

187

Page 202: Adaptive Server Anywhere

示例嵌入式 SQL 程序

❖ 运行静态游标示例程序:运行静态游标示例程序:运行静态游标示例程序:运行静态游标示例程序:

1 启动程序:

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

• 运行文件 Samples\ASA\C\curwnt.exe。

2 按照屏幕上的说明进行操作。

各种不同的命令可操纵数据库游标并在屏幕上显示查询结果。键入您希望执行的命令的字母,某些系统可能要求您在键入字母之后按 Enter 键。

❖ 运行动态游标示例程序:运行动态游标示例程序:运行动态游标示例程序:运行动态游标示例程序:

1 启动程序:

• 运行文件 Samples\ASA\C\dcurwnt.exe。

2 连接到数据库:

• 每个示例程序都提供一个控制台类型的用户界面并提示您

输入命令。输入以下连接字符串以连接到示例数据库:

DSN=ASA 8.0 Sample

3 选择一个表:

• 每个示例程序都提示您选择一个表。选择示例数据库中的

一个表。例如,您可以输入 Customer 或 Employee。

4 按照屏幕上的说明进行操作。

各种不同的命令可操纵数据库游标并在屏幕上显示查询结果。键入您希望执行的命令的字母,某些系统可能要求您在键入字母之后按 Enter 键。

Windows 示例示例示例示例 示例程序的 Windows 版是真正的 Windows 程序。但是,为了使用户界

面代码相对简单,已经进行了一些简化。特别是,这些应用程序除了重新打印提示之外,不会针对 WM_PAINT 消息重绘其 Windows。

188

Page 203: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

静态游标示例静态游标示例静态游标示例静态游标示例

本示例演示如何使用游标。此处使用的特定游标从示例数据库中的 employee 表检索某特定信息。游标是静态声明的,也就是说,检索信

息的实际 SQL 语句会被 " 硬编码 " 到源程序中。这是了解游标工作方式

的一个良好起点。下一个示例 (" 动态游标示例 " 第 189 页)采用第一

个示例并将其转换为使用动态 SQL 语句。

有关可以在何处找到源代码以及如何构建此示例程序的信息,请参阅 "示例嵌入式 SQL 程序 " 第 186 页。

open_cursor 例程声明特定 SQL 命令的游标并打开此游标。

显示信息页是由 print 例程完成的。它会循环 pagesize 次,从游标中读

取一行并将它显示输出。请注意, fetch 例程检查警告条件 (如 " 未找

到行 ")并显示这些条件出现时的相应消息。另外,此程序会将游标重

新定位到出现在当前数据页顶部的行之前的行。

move、 top 和 bottom 例程使用适当形式的 FETCH 语句来定位游标。

请注意,此形式的 FETCH 语句实际上不获取数据,它只定位游标。另

外, move 作为一个通用的相对定位例程,被设计成按照参数的符号上

下移动游标定位。

在用户退出时,会关闭游标,而且还会释放数据库连接。游标由 ROLLBACK WORK 语句关闭,而连接由 DISCONNECT 释放。

动态游标示例动态游标示例动态游标示例动态游标示例

本示例演示如何使用动态 SQL SELECT 语句的游标。它与静态游标示

例稍有不同。请先查看 " 静态游标示例 " 第 189 页(如果您尚未查看),

然后再查看本示例,这样会比较有帮助。

有关可以在何处找到源代码以及如何构建此示例程序的信息,请参阅 "示例嵌入式 SQL 程序 " 第 186 页。

dcur 程序允许用户选择要使用 n 命令查看的表。然后,该程序会根据

屏幕大小尽可能多地显示表中的信息。

在运行此程序时,它会提示输入以下形式的连接字符串:

189

Page 204: Adaptive Server Anywhere

示例嵌入式 SQL 程序

uid=DBA;pwd=SQL;dbf=c:\asa\asademo.db

含有嵌入式 SQL 的 C 程序位于您的 SQL Anywhere 目录的 Samples\ASA\C 子目录中。除了 connect、 open_cursor 和 print 函数

之外,此程序看起来很像静态游标示例。

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,这两个程序也可以作为服务运行。

190

Page 205: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

包含 Windows 服务的示例代码的两个文件是源文件 ntsvc.c 和头文件 ntsvc.h。该代码允许链接的可执行文件作为常规可执行文件或者作为 Windows 服务运行。

❖ 将所编译示例之一作为将所编译示例之一作为将所编译示例之一作为将所编译示例之一作为 Windows 服务运行:服务运行:服务运行:服务运行:

1 启动 Sybase Central 并打开 Services 文件夹。

2 选择示例应用程序的一种服务类型,然后单击 " 确定 "。

3 在相应字段中输入服务名称。

4 从您的 SQL Anywhere 目录中的 Samples\ASA\C 子目录中,选

择示例程序 (curwnt.exe 或 dcurwnt.exe)。

5 单击 " 确定 " 以安装服务。

6 在主窗口中单击 " 启动 " 以启动服务。

在作为服务运行时,如有可能程序会显示普通用户界面。这些程序还会将输出写入 " 应用程序事件日志 "。如果无法启动用户界面,则程序会

将一页数据打印到 " 应用程序事件日志 ",然后停止。

已经使用 Watcom C/C++ 10.5 编译器和 Microsoft Visual C++ 编译器对这

些示例进行了测试。

191

Page 206: Adaptive Server Anywhere

嵌入式 SQL 数据类型

嵌入式嵌入式嵌入式嵌入式 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 :以空值终止的字符串,是一个有效时间。

192

Page 207: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

• 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 型值 " 第 235 页。

• DT_BINARY :具有双字节长度字段的变长二进制数据。在为数

据库服务器提供信息时,您必须设置长度字段。在从数据库服务器读取信息时,服务器设置长度字段。

typedef struct BINARY { unsigned short int len; char array[1];} BINARY;

• DT_LONGBINARY :长型二进制数据。下面的宏定义一个结

构:

193

Page 208: Adaptive Server Anywhere

嵌入式 SQL 数据类型

#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 型值 " 第 235 页。

• 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 成员。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 " 中的 DATE_FORMAT、 TIME_FORMAT、 TIMESTAMP_FORMAT 和 DATE_ORDER 等数据库选项。

194

Page 209: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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

这些结构在 sqlca.h 文件中定义。 VARCHAR、 BINARY 和 DECIMAL 类型包含一个单字符数组,因此,它们对于声明主机变量没

有用,但是,对于动态分配变量或强制转换其它变量的类型有用。

DATE 和和和和 TIME 数数数数据库类型据库类型据库类型据库类型

对于各种不同的 DATE 和 TIME 数据库类型,没有对应的嵌入式 SQL 接口数据类型。这些数据库类型都是使用 SQLDATETIME 结构或字符

串读取和更新的。

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > GET DATA 语句 [ESQL]" 和 "ASA SQL 参考手册 > SQL 语句 > SET 语句 "。

195

Page 210: Adaptive Server Anywhere

使用主机变量

使用主机变量使用主机变量使用主机变量使用主机变量

主机变量是对 SQL 预处理器标识的 C 变量。主机变量可用于将值发送

到数据库服务器或从数据库服务器接收值。

主机变量非常易于使用,但是它们具有一些限制。动态 SQL 是一种向

数据库服务器和从数据库服务器中传递信息的更常用的方法,它使用被称为 "SQL 描述符区域 "(SQLDA) 的结构。 SQL 预处理器为使用主机变

量的每个语句自动生成 SQLDA。

有关动态 SQL 的信息,请参阅 " 静态和动态 SQL" 第 220 页。

声明主机变量声明主机变量声明主机变量声明主机变量

主机变量是通过将它们放入 " 声明部分声明部分声明部分声明部分 " 来定义的。按照 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

196

Page 211: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

values*/EXEC SQL INSERT INTO EmployeeVALUES (:employee_number, :employee_name,:employee_initials, :employee_phone );

有关更广泛的示例,请参阅 " 静态游标示例 " 第 189 页。

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 字节浮点数。

197

Page 212: Adaptive Server Anywhere

使用主机变量

字符指针字符指针字符指针字符指针 声明为字符指针字符指针字符指针字符指针 (char *a) 的主机变量被数据库接口视为 32 767 字节长。

用于从数据库检索信息的字符指针字符指针字符指针字符指针类型的任何主机变量都必须指向一个缓冲区,该缓冲区的大小要足以保存可能从数据库返回的任何值。

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 个字节的字段的长型变长二进制数据。不是填补空白的。

C 数据类型数据类型数据类型数据类型 嵌入式嵌入式嵌入式嵌入式 SQL 接口类型接口类型接口类型接口类型 说明说明说明说明

198

Page 213: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

这具有相当大的潜在危险,因为可能会有人更改数据库中列的定义,使列比编写程序时更大。这可能会导致随机内存损坏问题。如果您使用的是 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 ...

}

199

Page 214: Adaptive Server Anywhere

使用主机变量

• 下面是无效的嵌入式 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 EmployeeVALUES (:employee_number, :employee_name,:employee_initials, :employee_phone:ind_phone );

200

Page 215: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

使用指示符变量处理使用指示符变量处理使用指示符变量处理使用指示符变量处理 NULL

在 SQL 数据中, NULL 代表未知的属性或不适用的信息。不要将 SQL 中 NULL 的概念与 C 语言中具有这一名称 (NULL) 的常量混淆。 C 常量

用于代表非初始化的或无效的指针。

当 NULL 在 Adaptive Server Anywhere 文档中使用时,它是指上面给出

的 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)。下一节

将介绍错误。

201

Page 216: Adaptive Server Anywhere

使用主机变量

将指示符变量用于截断值将指示符变量用于截断值将指示符变量用于截断值将指示符变量用于截断值

指示符变量指示某些读取值是否为适合主机变量而被截断了。这使应用程序可以正确地处理截断问题。

如果一个值在读取时被截断,则指示符变量会被设为正值,其中包含了在被截断前数据库值的实际长度。如果值的长度大于 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 警告

202

Page 217: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

有关检索 Long 型值的更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > GET DATA 语句 [ESQL]"。

< -2 NULL 值 NULL 结果

指示符的指示符的指示符的指示符的

值值值值向数据库提供值向数据库提供值向数据库提供值向数据库提供值 从数据库接收值从数据库接收值从数据库接收值从数据库接收值

203

Page 218: Adaptive Server Anywhere

SQL 通信区域 (SQLCA)

SQL 通信区域通信区域通信区域通信区域 (SQLCA)

"SQL 通信区域通信区域通信区域通信区域 "(SQLCA) 是一个存储区域,将统计和错误从应用程序

传递到数据库服务器再传回应用程序的每个数据库请求会使用它。SQLCA 被用作应用程序与数据库的通信链路的句柄。它会被传递到需

要与数据库服务器进行通信的所有数据库库函数中。它会在所有嵌入式 SQL 语句上被隐式传递。

全局 SQLCA 变量在接口库中定义。预处理器会为全局 SQLCA 变量生

成外部引用,并且会为该变量的指针生成外部引用。外部引用名为 sqlca,类型为 SQLCA。指针名为 sqlcaptr。实际的全局变量在导入库

中声明。

SQLCA 由 sqlca.h 头文件定义,该文件包括在安装目录的 h 子目录

中。

SQLCA 提供错误代提供错误代提供错误代提供错误代

码码码码

引用 SQLCA 是为了测试特定的错误代码。当数据库请求有错误时 (见

下文), sqlcode 和 sqlstate 字段包含错误代码。某些 C 宏是为引用 sqlcode 字段、 sqlstate 字段和某些其它字段而定义的。

SQLCA 字段字段字段字段

SQLCA 中的字段具有以下含义:

• sqlcaid :一个 8 字节字符字段,包含字符串 SQLCA,用作 SQLCA 结构的标识。此字段有助于您在查看内存内容时进行调

试。

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

• sqlcode :一个长型整数,在数据库检测到请求错误时指定错误

代码。错误代码的定义可以在头文件 sqlerr.h 中找到。成功操

作的错误代码是 0 (零),正数表示警告,负数表示错误。

有关错误代码的完整列表,请参阅 "ASA 错误消息 > 数据库错误

消息 "。

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

204

Page 219: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

• 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 语句语句语句语句 :受语句影

响的行数。

205

Page 220: Adaptive Server Anywhere

SQL 通信区域 (SQLCA)

在游标 OPEN 上,既可以使用游标中的实际行数 (大于或等

于 0 的值),也可以使用行数的估计值 (其绝对值为估计值

的负数)填充此字段。如果数据库服务器不统计该值即可计算出行数,则该值就是实际行数。也可以使用 ROW_COUNT 选项,将数据库配置为始终返回实际的行数。

• FETCH 游标语句游标语句游标语句游标语句 :如果返回 SQLE_NOTFOUND 警告,则

填充 SQLCOUNT 字段。它包含 FETCH RELATIVE 或 FETCH ABSOLUTE 语句超出可能的游标位置 (游标可以位

于某一行上、第一行之前或 后一行之后)范围之外的行数。在宽读取的情况下, SQLCOUNT 是实际读取的行数,

它小于或等于请求的行数。在宽读取过程中,不 设置 SQLE_NOTFOUND。

有关宽读取的更多信息,请参阅 " 一次读取多个行 " 第 214页。

如果未找到行但位置有效,则值为 0,例如,当定位在游标

的 后一行上时执行 FETCH RELATIVE 1。如果尝试的读取

超出游标的末尾,则值为正数;如果尝试的读取在游标的开头之前,则值为负数。

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

• DESCRIBE 语句语句语句语句 :在用于说明可能具有多个结果集的过程

的 WITH VARIABLE RESULT 子句中, SQLCOUNT 设置为

以下值之一:

• 0 :结果集可能会有变化:在每个 OPEN 语句之后应

再次说明过程调用。

• 1 :结果集保持不变。不需要再次进行说明。

在出现语法错误 SQLE_SYNTAX_ERROR 的情况下,此字段

包含命令字符串内检测到错误的大致字符位置。

• sqlerrd[3] (SQLIOESTIMATE) :完成命令所需的输入 / 输出操

作的估计数。在 OPEN 或 EXPLAIN 命令上将给此字段赋一个值。

206

Page 221: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

多线程代码或再入式代码的多线程代码或再入式代码的多线程代码或再入式代码的多线程代码或再入式代码的 SQLCA 管理管理管理管理

您可以在多线程代码或再入式代码中使用嵌入式 SQL 语句。但是,如

果您使用单个连接,则对于每个连接您只能有一个活动请求。在多线程应用程序中,除非使用信号控制访问,否则在每个线程上不应使用到数据库的同一连接。

对于在希望使用数据库的每个线程上使用单独的连接没有限制。运行时库使用 SQLCA 来区分不同的线程上下文。因此,希望使用数据库的每

个线程都必须具有它自己的 SQLCA。

任何给定的数据库连接都只能从一个 SQLCA 访问,但取消指令除外,

此指令必须从单独的线程发出。

有关取消请求的信息,请参阅 " 实现请求管理 " 第 245 页。

使用多个使用多个使用多个使用多个 SQLCA

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

1 您必须在 SQL 预处理器上使用生成再入式代码的选项 (-r)。由

于无法使用静态初始化的全局变量,因此再入式代码稍大且速度稍慢。不过,这些影响是很小的。

2 必须使用对 db_init 的调用来初始化程序中使用的每个 SQLCA,而在这些 SQLCA 的结尾处,必用使用对 db_fini 的调

用进行清除。

警告警告警告警告对于 NetWare 上的每个 db_init,如果未能调用 db_fini,则会导致

数据库服务器和 NetWare 文件服务器出现故障。

3 嵌入式 SQL 语句 SET SQLCA ("ASA SQL 参考手册 > SQL 语句 > SET SQLCA 语句 [ESQL]")用于通知 SQL 预处理器为数

据库请求使用别的 SQLCA。在程序顶部或头文件中,通常会使

用类似 EXEC SQL SET SQLCA 'task_data->sqlca'; 这样的一条语

207

Page 222: Adaptive Server Anywhere

SQL 通信区域 (SQLCA)

句,将 SQLCA 引用设置为指向任务特定的数据。此语句不生

成任何代码,因此对性能没有影响。它更改预处理器内的状态,以便对 SQLCA 的任何引用都使用给定的字符串。

有关创建 SQLCA 的信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > 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 以连接到多个数据库或具有到单个数据库的多

个连接。

208

Page 223: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

每个 SQLCA 都可以具有一个未命名的连接。每个 SQLCA 都具有一个

活动的或当前的连接 (请参阅 "ASA SQL 参考手册 > SQL 语句 > SET CONNECTION 语句 [Interactive SQL] [ESQL]")。在所给定数据库连接

上进行的所有操作都必须使用建立数据库连接时所使用的同一个 SQLCA。

记录锁定记录锁定记录锁定记录锁定不同连接上的操作受常规记录锁定机制的影响,并且可能导致互相阻塞,甚至可能导致死锁。有关锁定的信息,请参阅 "ASA SQL 用户指南 > 使用事务和隔离级别 " 一章。

209

Page 224: Adaptive Server Anywhere

读取数据

读取数据读取数据读取数据读取数据

读取嵌入式 SQL 中的数据是通过使用 SELECT 语句来完成的。有以下

两种情况:

• 多返回一行的多返回一行的多返回一行的多返回一行的 SELECT 语句语句语句语句 :使用 INTO 子句将返回的值直

接指派给主机变量。

有关信息,请参阅 " 多返回一行的 SELECT 语句 " 第 210 页。

• SELECT 语句可能返回多行语句可能返回多行语句可能返回多行语句可能返回多行 :使用游标管理结果集的行。

有关更多信息,请参阅 " 在嵌入式 SQL 中使用游标 " 第 211 页。

LONG VARCHAR 和 LONG BINARY 数据类型的处理方式与其它数据

类型不同。有关更多信息,请参阅 " 检索 LONG 数据 " 第 236 页。

多返回一行的多返回一行的多返回一行的多返回一行的 SELECT 语句语句语句语句

单行查询 多从数据库中检索一行。单行查询 SELECT 语句在选择列表

之后和 FROM 子句之前有一个 INTO 子句。 INTO 子句包含一组主机变

量,用于接收每个选择列表项的值。主机变量数必须与选择列表项的数量相同。主机变量可能伴随有指示 NULL 结果的指示符变量。

当执行 SELECT 语句时,数据库服务器检索结果并将其放在主机变量

中。如果查询结果包含多个行,则数据库服务器会返回一个错误。

如果查询结果中没有选定的行,则返回 " 未找到行 " 警告。如 "SQL 通信

区域 (SQLCA)" 第 204 页中所述,错误和警告在 SQLCA 结构中返回。

示例示例示例示例 例如,如果成功地从 employee 表读取了一行,则以下代码段返回 1 ;

如果该行不存在则返回 0 ;如果出现错误则返回 -1。

EXEC SQL BEGIN DECLARE SECTION;long emp_id;char name[41];char sex;char birthdate[15];short intind_birthdate;

EXEC SQL END DECLARE SECTION;. . .

210

Page 225: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

int find_employee( long employee ){

emp_id = employee;EXEC SQL SELECT emp_fname ||

' ' || emp_lname, sex, birth_dateINTO :name, :sex,

:birthdate:ind_birthdateFROM "DBA".employeeWHERE emp_id = :emp_id;

if( SQLCODE == SQLE_NOTFOUND ) {return( 0 ); /* employee not found */

} else if( SQLCODE < 0 ) {return( -1 ); /* error */

} else {return( 1 ); /* found */

}}

在嵌入式在嵌入式在嵌入式在嵌入式 SQL 中使用游标中使用游标中使用游标中使用游标

游标用于从其结果集中具有多个行的查询中检索行。 " 游标游标游标游标 " 是 SQL 查询的句柄或标识符和结果集中的一个位置。

有关游标的简介,请参阅 " 使用游标 " 第 20 页。

❖ 在嵌入式在嵌入式在嵌入式在嵌入式 SQL 中管理游标:中管理游标:中管理游标:中管理游标:

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

2 使用 OPEN 语句打开游标。

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

4 读取行,直到返回 " 未找到行 " 警告。

如 "SQL 通信区域 (SQLCA)" 第 204 页中所述,错误和警告在 SQLCA 结构中返回。

5 使用 CLOSE 语句关闭游标。

211

Page 226: Adaptive Server Anywhere

读取数据

缺省情况下,在事务 (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

SELECTemp_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 < 0 ) {break;

}if( ind_birthdate < 0 ) {

strcpy( birthdate, "UNKNOWN" );}printf( "Name: %s Sex: %c Birthdate:

%s.n",name, sex, birthdate );}

EXEC SQL CLOSE C1;}

有关使用游标的完整示例,请参阅 " 静态游标示例 " 第 189 页和 " 动态游

标示例 " 第 189 页。

212

Page 227: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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

• 在某一行上

• 在第一行之前

• 在 后一行之后

在打开游标时,它被定位在第一行之前。使用 FETCH 命令可移动游标

位置 (请参阅 "ASA SQL 参考手册 > SQL 语句 > FETCH 语句 [ESQL] [SP]")。可以将游标定位到相对查询结果开头或结尾的一个绝对位置。

也可以相对当前游标位置移动它。

0

1

2

3

n ? 2

n ? 1

n

n + 1

? ? 1

?

? + 1

? + 2

?

?

?

0After last row

Before first row

Absolute rowfrom start

Absolute rowfrom end

从开始算起的绝对行号

从结尾算起的绝对行号

-n-1

-n

-n+1

-n+2

-3

-2

-1

0

0

1

2

3

n-2

n-1

n

n+1

第一行之前

后一行之前

213

Page 228: Adaptive Server Anywhere

读取数据

UPDATE 和 DELETE 语句有一些特殊的定位 版本,可用于更新或删除

游标当前位置处的行。如果将游标定位在第一行之前或 后一行之后,则返回 " 没有当前的游标行 " 错误。

可以使用 PUT 语句向游标中插入行。

游标定位问题游标定位问题游标定位问题游标定位问题 对 DYNAMIC SCROLL 游标的插入和某些更新会导致游标定位问题。

除非在 SELECT 语句中有一个 ORDER BY 子句,否则数据库服务器不

会将插入的行放在游标中的预计位置。在有些情况下,插入的行要等到关闭并再次打开游标后才会出现。

对于 Adaptive Server Anywhere,如果必须创建临时表才能打开游标,则

会出现这种情况。

有关说明,请参阅 "ASA SQL 用户指南 > 监控和提高性能 > 在查询处理

中使用工作表 "。

UPDATE 语句可能导致行在游标中移动。如果游标具有一个使用现有索

引 (未创建临时表)的 ORDER BY 子句,则会出现这种情况。

一次读取多个行一次读取多个行一次读取多个行一次读取多个行

可以将 FETCH 语句修改为一次读取多行,这样可能会改善性能。这种

方式被称为 " 宽读取宽读取宽读取宽读取 " 或 " 数组读取数组读取数组读取数组读取 "。

Adaptive Server Anywhere 还支持宽放置和宽插入。有关它们的信息,请

参阅 "ASA SQL 参考手册 > SQL 语句 > PUT 语句 [ESQL]" 和 "ASA SQL 参考手册 > SQL 语句 > EXECUTE 语句 [ESQL]"。

要在嵌入式 SQL 中使用宽读取,请将 fetch 语句包括在代码中,如下所

示:

EXEC SQL FETCH . . . ARRAY nnn

其中 ARRAY nnn 是 FETCH 语句的 后一项。读取计数 nnn 可以是一个

主机变量。 SQLDA 中的变量数必须是 nnn 和每行的列数的乘积。第一

行放在 SQLDA 变量 0 到 (每行的列数) -1 中,以此类推。

SQLDA 的每一行中的每一列的类型必须相同,否则会返回 SQLDA_INCONSISTENT 错误。

214

Page 229: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

服务器在 SQLCOUNT 中返回读取的记录数,除非有错误或警告,否则

该记录数始终大于零。在宽读取时,在没有错误的情况下,SQLCOUNT 为一 (1) 指示已经读取一个有效行。

示例示例示例示例 下面的示例代码说明如何使用宽读取。您也可以在 SQL Anywhere 目录

的 samples\ASA\esqlwidefetch\widefetch.sqc 中找到此代码。

#include <stdio.h>#include <stdlib.h>#include <string.h>#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_numberstat0,unsignedwidth,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;

215

Page 230: Adaptive Server Anywhere

读取数据

*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 < width; row++ ) { for( col = 0;

col < num_cols; col++, offset++ ) { sqlda->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 < rows_fetched; row++ ) {

for( col = 0; col < cols_per_row; col++ ) {

216

Page 231: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

offset = row * cols_per_row + col; printf( " \"%s\",

(char *)sqlda->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 );}

217

Page 232: Adaptive Server Anywhere

读取数据

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 < 2 ) {

fetch_width = 2; }}

} db_init( &sqlca ); EXEC SQL CONNECT "dba" IDENTIFIED BY "sql"; DoQuery( query_str, fetch_width ); EXEC SQL DISCONNECT;err: db_fini( &sqlca );}

有关使用宽读取的注有关使用宽读取的注有关使用宽读取的注有关使用宽读取的注意事项意事项意事项意事项

• 在函数 PrepareSQLDA 中, SQLDA 内存是使用 alloc_sqlda 函数

分配的。这样就为指示符变量留出了空间,而不用使用 alloc_sqlda_noind 函数。

• 如果读取的行数小于请求的行数,但又不是零 (例如在游标的末

尾),则通过设置指示符值可将对应于未读取的行的 SQLDA 项作

为 NULL 返回。如果不存在指示符变量,则生成一个错误

(SQLE_NO_INDICATOR:NULL 结果没有指示符变量)。

• 如果正在读取的行已经更新,并且生成了 SQLE_ROW_UPDATED_WARNING 警告,那么,读取到导致警

告的行时就会停止。将返回处理到该点的所有行 (包括导致警告的行)的值。 SQLCOUNT 包含读取的行数,其中包括导致警告

的行。所有剩余的 SQLDA 项都被标记为 NULL。

218

Page 233: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

• 如果正在读取的行已经被删除或锁定,并且生成了 SQLE_NO_CURRENT_ROW 或 SQLE_LOCKED 错误,则 SQLCOUNT 包含出错前读取的行数。这不包括导致错误的行。

SQLDA 不包含任何行的值,因为出现错误时不返回 SQLDA 值。

如果必要,可使用 SQLCOUNT 值来重新定位游标,以便读取行。

219

Page 234: Adaptive Server Anywhere

静态和动态 SQL

静态和动态静态和动态静态和动态静态和动态 SQL

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

• 静态语句

• 动态语句

在此之前,我们一直在讨论静态 SQL。本节将对静态 SQL 和动态 SQL 进行比较。

静态静态静态静态 SQL 语句语句语句语句

通过在标准 SQL 数据操纵语句和数据定义语句之前加上 EXEC SQL 并在命令之后加上分号 (;),可以将所有这些语句嵌入到 C 程序中。这些

语句称为 " 静态静态静态静态 " 语句。

如 " 使用主机变量 " 第 196 页中所述,静态语句可以包含对主机变量的

引用。此前的所有示例中使用的都是静态嵌入式 SQL 语句。

主机变量只能用来代替字符串或数字常量,不能用来代替列名或表名;执行那些操作需要使用动态语句。

动态动态动态动态 SQL 语句语句语句语句

在 C 语言中,字符串存储在字符数组中。动态语句是用 C 语言字符串

构造的。然后,可以使用 PREPARE 和 EXECUTE 语句执行这些语句。

这些 SQL 语句无法按与静态语句相同的方式引用主机变量,因为在执

行 C 程序时无法按名称访问 C 语言变量。

要在语句和 C 语言变量之间传递信息,请使用名为 "SQL 描述符区域描述符区域描述符区域描述符区域

"(SQLDA) 的数据结构。如果您在 EXECUTE 命令的 USING 子句中指

定一组主机变量,则 SQL 预处理器会为您建立此结构。这些变量按位

置对应于准备好的命令字符串相应位置中的占位符。

有关 SQLDA 的信息,请参阅 "SQL 描述符区域 (SQLDA)" 第 225 页。

220

Page 235: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

将 " 占位符占位符占位符占位符 " 放在语句中是为了指示要访问主机变量的位置。占位符可

以是问号 (?),或者也可以是静态语句中的主机变量引用 (主机变量名

之前有一个冒号)。在后一种情况下,在语句的实际文本中使用的主机变量名仅充当占位符,指示对 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 puta limit on it */

221

Page 236: Adaptive Server Anywhere

静态和动态 SQL

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 onname fields in sqlda */. . .EXEC SQL EXECUTE S1 USING DESCRIPTOR sqlda;free_sqlda( sqlda );

SQLDA 的内容的内容的内容的内容 SQLDA 包含一组变量描述符。每个描述符说明对应的 C 程序变量的属

性或者数据库存储数据的位置或检索数据的位置:

• 数据类型

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

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

• 内存地址

• 指示符变量

有关 SQLDA 结构的完整说明,请参阅 "SQL 描述符区域 (SQLDA)" 第225 页

指示符变量和指示符变量和指示符变量和指示符变量和 NULL

指示符变量用于将 NULL 值传递到数据库或从数据库检索 NULL 值。

指示符变量还由数据库服务器用来指示在数据库操作过程中遇到的截断条件。当提供的空间不足,无法接收数据库值时,会将指示符变量设置为正值。

有关更多信息,请参阅 " 指示符变量 " 第 200 页。

动态动态动态动态 SELECT 语句语句语句语句

可以动态准备仅返回单个行的 SELECT 语句,后跟带 INTO 子句的 EXECUTE 以检索单行结果。但是,返回多个行的 SELECT 语句是使用

动态游标管理的。

222

Page 237: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

使用动态游标时,将结果放在在 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 firstDESCRIBE 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;

223

Page 238: Adaptive Server Anywhere

静态和动态 SQL

使用后删除语句使用后删除语句使用后删除语句使用后删除语句为避免占用不必要的资源,请确保在使用语句后将其删除。

有关使用动态选择语句的游标的完整示例,请参阅 " 动态游标示例 " 第189 页。

有关上述函数的详细信息,请参阅 " 库函数参考 " 第 251 页。

224

Page 239: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

SQL 描述符区域描述符区域描述符区域描述符区域 (SQLDA)

SQLDA (SQL 描述符区域)是一个用于动态 SQL 语句的接口结构。此

结构可将有关主机变量和 SELECT 语句结果的信息传入和传出数据库。

SQLDA 在头文件 sqlda.h 中定义。

数据库接口库或 DLL 中有可用于管理 SQLDA 的函数。有关说明,请

参阅 " 库函数参考 " 第 251 页。

当主机变量与静态 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 _sqlfartypedefshort int a_SQL_type;struct sqlname { short int length; /* length of char data */ chardata[ 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 _sqldafar *sqldata; /* address of variable */ short int _sqldafar *sqlind; /* indicator variable pointer */ struct sqlname sqlname;};struct sqlda{ unsigned char sqldaid[8]; /* eye catcher "SQLDA"*/

225

Page 240: Adaptive Server Anywhere

SQL 描述符区域 (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 数组中包含的变量描述符数。

226

Page 241: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

SQLDA 主机变量说明主机变量说明主机变量说明主机变量说明

SQLDA 中的每个 sqlvar 结构都说明一个主机变量。 sqlvar 结构的各字

段的含义如下:

• sqltype :此描述符描述的变量的类型 (请参阅 " 嵌入式 SQL 数据类型 " 第 192 页)。

低序位指示是否允许使用 NULL 值。有效的类型和常量定义可以

在 sqldef.h 头文件中找到。

此字段由 DESCRIBE 语句填充。在向数据库服务器提供数据或从

中检索数据时,您可以将此字段设置为任何类型。任何必需的类型转换都会自动完成。

• sqllen :变量的长度。该长度的实际含义取决于类型信息和 SQLDA 的使用方式。

对于 DECIMAL 类型,此字段分为两个 1 字节字段。高字节是精

度,低字节是小数位数。精度是总位数。小数位数是小数点之后的位数。

对于 LONG VARCHAR 和 LONG BINARY 数据类型,使用 DT_LONGBINARY 和 DT_LONGVARCHAR 数据类型结构的 array_len 字段,而不是使用 sqllen 字段。

有关长度字段的更多信息,请参阅 "SQLDA sqllen 字段值 " 第 229页。

• sqldata :指向此变量所占用的内存的四字节指针。此内存必须

对应于 sqltype 和 sqllen 字段。

sqld 有效的变量描述符 (包含说明主机变量的信息)的数目。在向数据库服务器提供数据时,此字段由 DESCRIBE 语句

设置,在向数据库服务器提供数据时,有时由程序员设置。

sqlvar 一组类型为 struct sqlvar 的描述符,每个描述符描述一个

主机变量。

字段字段字段字段 说明说明说明说明

227

Page 242: Adaptive Server Anywhere

SQL 描述符区域 (SQLDA)

有关存储格式的信息,请参阅 " 嵌入式 SQL 数据类型 " 第 192 页。

对于 UPDATE 和 INSERT 命令,如果 sqldata 指针是空指针,操作

中就不会涉及此变量。对于 FETCH,如果 sqldata 指针是空指针,

则不返回数据。换句话说, sqldata 指针返回的列是 " 未绑定列未绑定列未绑定列未绑定列

"。

如果 DESCRIBE 语句使用 LONG NAMES,则此字段保存结果集

列的长名称。另外,如果 DESCRIBE 语句是 DESCRIBE USER TYPES 语句,则此字段保存用户定义的数据类型的长名称,而不

是列的长名称。如果该类型是基类型,则此字段为空。

• sqlind :指向指示符值的指针。指示符值是 short int。负的指示

符值表示是 NULL 值。正的指示符值表示此变量已经被 FETCH 语句截断,且指示符值包含截断前的数据长度。如果将 CONVERSION_ERROR 数据库选项设置为 OFF,则值 -2 表示出

现了转换错误。

有关更多信息,请参阅 " 指示符变量 " 第 200 页。

如果 sqlind 指针是空指针,则说明没有适用于此主机变量的指示

符变量。

DESCRIBE 语句也使用 sqlind 字段来指示参数类型。如果类型是

用户定义的数据类型,则此字段将设置为 DT_HAS_USERTYPE_INFO。在这种情况下,您可能希望执行 DESCRIBE USER TYPES 以获得有关用户定义的数据类型的信

息。

• sqlname :包含一个长度和一个字符缓冲区的功能类似 VARCHAR 的结构。它由 DESCRIBE 语句填充,在其它情况下不

使用它。对于以下两种格式的 DESCRIBE 语句,此字段具有不同

的含义:

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

填充。

• BIND VARIABLES :名称缓冲区由曾用作绑定变量的主机

变量的名称填充,或者,如果使用了未命名的参数标记,则用 "?" 填充。

228

Page 243: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

在 DESCRIBE SELECT LIST 命令中,出现的任何指示符变量都会

用一个标志 (指示选择列表项是否可更新)来填充。有关此标志的更多信息可以在 sqldef.h 头文件中找到。

如果 DESCRIBE 语句是 DESCRIBE USER TYPES 语句,则此字段

保存用户定义数据类型的长名称,而不是列的长名称。如果该类型是一个基类型,则此字段为空。

SQLDA sqllen 字段值字段值字段值字段值

在 SQLDA 中, sqlvar 结构的 sqllen 字段长度在与数据库服务器进行以

下种类的交互作用时使用:

• 说明值说明值说明值说明值 :DESCRIBE 语句获取有关主机变量的信息 (这些主机

变量是存储从数据库检索的数据或将数据传递到数据库时所必需的)。

请参阅 " 说明值 " 第 230 页。

• 检索值检索值检索值检索值 :从数据库检索值。

请参阅 " 检索值 " 第 232 页。

• 发送值发送值发送值发送值 :向数据库发送信息。

请参阅 " 发送值 " 第 231 页。

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

下表逐一详细说明了这些交互作用。这些表列出在 sqldef.h 头文件中

找到的接口常量类型(DT_ 类型)。这些常量应放在 SQLDA sqltype 字段中。

有关 sqltype 字段值的信息,请参阅 " 嵌入式 SQL 数据类型 " 第 192 页。

在静态 SQL 中,也会使用 SQLDA,但它是由 SQL 预处理器生成并完

全填充的。在这种静态情况下,这些表给出静态 C 语言主机变量类型和

接口常量之间的对应关系。

229

Page 244: Adaptive Server Anywhere

SQL 描述符区域 (SQLDA)

说明值说明值说明值说明值

下表为各种数据库类型指明由 DESCRIBE 命令返回的 sqllen 和 sqltype 结构成员的值(SELECT LIST 和 BIND VARIABLE DESCRIBE 语句)。

在用户定义的数据库数据类型的情况下,则对基类型进行说明。

您的程序可以使用从 DESCRIBE 返回的类型和长度,或者您可以使用

另一种类型。数据库服务器在任意两种类型之间执行类型转换。由 sqldata 字段指向的内存必须对应于 sqltype 和 sqllen 字段。

有关嵌入式 SQL 数据类型的信息,请参阅 " 嵌入式 SQL 数据类型 " 第192 页。

数据库字段类型数据库字段类型数据库字段类型数据库字段类型返回的嵌入式返回的嵌入式返回的嵌入式返回的嵌入式 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

230

Page 245: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

发送值发送值发送值发送值

下表指明当您向数据库服务器提供数据时指定 SQLDA 中值的长度的方

式。

在这种情况下,只允许使用表中显示的数据类型。在向数据库提供信息时,将 DT_DATE、 DT_TIME 和 DT_TIMESTAMP 类型视为与 DT_STRING 相同;值必须是具有适当日期格式且以空值终止的字符

串。

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

数据库字段类型数据库字段类型数据库字段类型数据库字段类型返回的嵌入式返回的嵌入式返回的嵌入式返回的嵌入式 SQL 类类类类型型型型

说明时返回的长度说明时返回的长度说明时返回的长度说明时返回的长度

嵌入式嵌入式嵌入式嵌入式 SQL 数据类型数据类型数据类型数据类型 设置长度的程序操作设置长度的程序操作设置长度的程序操作设置长度的程序操作

DT_BIGINT 不需要任何操作

DT_BINARY(n) 采用 BINARY 结构中的字段的长度

DT_BIT 不需要任何操作

DT_DATE 由终止的 \0 决定的长度

DT_DECIMAL(p,s) SQLDA 中长度字段的高字节设置为 p,低

字节设置为 s

DT_DOUBLE 不需要任何操作

231

Page 246: Adaptive Server Anywhere

SQL 描述符区域 (SQLDA)

检索值检索值检索值检索值

下表指明在使用 SQLDA 从数据库中检索数据时长度字段的值。在检索

数据时,从不修改 sqllen 字段。

在这种情况下,只允许使用表中显示的接口数据类型。在从数据库检索信息时,使用 DT_DATE、 DT_TIME 和 DT_TIMESTAMP 数据类型与

使用 DT_STRING 的方式是相同的。值会被设置为当前日期格式的字符

串。

DT_FIXCHAR(n) SQLDA 中的长度字段决定字符串的长度

DT_FLOAT 不需要任何操作

DT_INT 不需要任何操作

DT_LONGBINARY 忽略长度字段。请参阅 " 发送 LONG 数据 " 第 238 页

DT_LONGVARCHAR 忽略长度字段。请参阅 " 发送 LONG 数据 " 第 238 页

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 决定的长度

嵌入式嵌入式嵌入式嵌入式 SQL 数据类型数据类型数据类型数据类型 设置长度的程序操作设置长度的程序操作设置长度的程序操作设置长度的程序操作

232

Page 247: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

嵌入式嵌入式嵌入式嵌入式 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 数据 " 第236 页

忽略长度字段。请参阅 "检索 LONG 数据 " 第236 页

DT_LONGVARCHAR 忽略长度字段。请参阅 "检索 LONG 数据 " 第236 页

忽略长度字段。请参阅 "检索 LONG 数据 " 第236 页

DT_SMALLINT 不需要任何操作 不需要任何操作

DT_STRING 缓冲区的长度 \0 位于字符串的末尾

DT_TIME 缓冲区的长度 \0 位于字符串的末尾

DT_TIMESTAMP 缓冲区的长度 \0 位于字符串的末尾

DT_TIMESTAMP_ STRUCT

不需要任何操作 不需要任何操作

DT_UNSBIGINT 不需要任何操作 不需要任何操作

DT_UNSINT 不需要任何操作 不需要任何操作

233

Page 248: Adaptive Server Anywhere

SQL 描述符区域 (SQLDA)

DT_UNSSMALLINT 不需要任何操作 不需要任何操作

DT_VARCHAR(n) VARCHAR 结构的 大

长度 (n+2)将 VARCHAR 结构的 len 字段设置为实际长

嵌入式嵌入式嵌入式嵌入式 SQL 数据类数据类数据类数据类

型型型型

在接收时程序必须将长在接收时程序必须将长在接收时程序必须将长在接收时程序必须将长

度字段设置为度字段设置为度字段设置为度字段设置为

在读取值之后数据库返在读取值之后数据库返在读取值之后数据库返在读取值之后数据库返

回长度信息的方式回长度信息的方式回长度信息的方式回长度信息的方式

234

Page 249: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

发送和检索发送和检索发送和检索发送和检索 Long 型值型值型值型值

在嵌入式 SQL 应用程序中,发送和检索 LONG VARCHAR 值和 LONG BINARY 值的方法与发送和检索其它数据类型的值的方法不同。虽然可

以使用标准 SQLDA 字段,但是它们包含的数据不得超过 32 kb,因为

保存信息的字段 (sqldata、 sqllen 和 sqlind)是 16 位值。将这些值更改

为 32 位值会破坏现有的应用程序。

说明 LONG VARCHAR 值和 LONG BINARY 值的方法与说明其它数据

类型的方法相同。

有关如何检索和发送值的信息,请参阅 " 检索 LONG 数据 " 第 236 页和 "发送 LONG 数据 " 第 238 页。

静态静态静态静态 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) */

235

Page 250: Adaptive Server Anywhere

发送和检索 Long 型值

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 数据 " 第 236 页和 " 发送 LONG 数据 " 第 238 页。

检索检索检索检索 LONG 数据数据数据数据

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

检索 Long 型值 " 第 235 页。

使用静态 SQL 时与使用动态 SQL 时的检索过程不同。

❖ 接收接收接收接收 LONG VARCHAR 或或或或 LONG BINARY 值 (静态值 (静态值 (静态值 (静态 SQL):):):):

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

2 使用 FETCH、 GET DATA 或 EXECUTE INTO 检索数据。

Adaptive Server Anywhere 设置以下信息:

• 指示符变量指示符变量指示符变量指示符变量 :指示符变量在值为 NULL 时为负,在未发

生截断时为 0,在发生截断时为未截断值的字节数 (不超

过 32767 的正数)。

有关更多信息,请参阅 " 指示符变量 " 第 200 页。

• stored_len :此 DECL_LONGVARCHAR 或 DECL_LONGBINARY 字段保存检索到数组中的字节数。

它从不大于 array_len。

• untrunc_len :此 DECL_LONGVARCHAR 或 DECL_LONGBINARY 字段保存数据库服务器所保存的字

节数。它至少等于 stored_len 值。即使不截断值也会设置

它。

236

Page 251: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

❖ 将值接收到将值接收到将值接收到将值接收到 LONGVARCHAR 或或或或 LONGBINARY 结构中结构中结构中结构中

(动态(动态(动态(动态 SQL):):):):

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

2 将 sqldata 字段设置为指向 LONGVARCHAR 或 LONGBINARY 结构。

您可以使用 LONGVARCHARSIZE( n ) 宏或 LONGBINARYSIZE( n ) 宏来确定为保存数组字段中的 n 字节数据而分配的总字节数。

3 将 LONGVARCHAR 或 LONGBINARY 结构的 array_len 字段设

置为分配给数组字段的字节数。

4 使用 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 128000void get_test_var()/*****************/{ LONGVARCHAR *longptr; SQLDA *sqlda; SQLVAR *sqlvar; sqlda = alloc_sqlda( 1 ); longptr = (LONGVARCHAR *)malloc( LONGVARCHARSIZE( DATA_LEN ) ); if( sqlda == NULL || longptr == NULL ) {

237

Page 252: Adaptive Server Anywhere

发送和检索 Long 型值

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 型值 " 第 235 页。

使用静态 SQL 时与使用动态 SQL 时的检索过程不同。

❖ 发送发送发送发送 LONG VARCHAR 或或或或 LONG BINARY 值 (静态值 (静态值 (静态值 (静态 SQL):):):):

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

2 如果您要发送 NULL,并且使用了指示符变量,请将指示符变

量设置为负值。

有关更多信息,请参阅 " 指示符变量 " 第 200 页。

238

Page 253: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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

4 通过打开游标或执行语句来发送数据。

下面的代码段说明使用静态嵌入式 SQL 发送 LONG VARCHAR 的机

制。它并不是为实际的应用程序而准备的。

#define DATA_LEN 12800EXEC SQL BEGIN DECLARE SECTION;// SQLPP initializes longdata.array_lenDECL_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;}

239

Page 254: Adaptive Server Anywhere

发送和检索 Long 型值

❖ 使用使用使用使用 LONGVARCHAR 或或或或 LONGBINARY 结构发送值 (动结构发送值 (动结构发送值 (动结构发送值 (动

态态态态 SQL):):):):

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

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

3 将 sqldata 字段设置为指向 LONGVARCHAR 或 LONGBINARY 结构。

您可以使用 LONGVARCHARSIZE( n ) 宏或 LONGBINARYSIZE( n ) 宏来确定为保存数组字段中的 n 字节数据而分配的总字节数。

4 将 LONGVARCHAR 或 LONGBINARY 结构的 array_len 字段设

置为分配给数组字段的字节数。

5 将 LONGVARCHAR 或 LONGBINARY 结构的 stored_len 字段

设置为数组字段中的数据字节数。它一定不能大于 array_len。

6 通过打开游标或执行语句发送数据。

240

Page 255: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

使用存储过程使用存储过程使用存储过程使用存储过程

本节说明如何在嵌入式 SQL 中使用 SQL 过程。

使用简单的存储过程使用简单的存储过程使用简单的存储过程使用简单的存储过程

您可以在嵌入式 SQL 中创建和调用存储过程。

您可以像嵌入任何其它数据定义语句 (如 CREATE TABLE)那样嵌入 CREATE PROCEDURE。您还可以嵌入 CALL 语句以执行存储过程。下

面的代码段说明如何在嵌入式 SQL 中创建和执行存储过程:

EXEC SQL CREATE PROCEDURE pettycash( IN amountDECIMAL(10,2) )

BEGINUPDATE accountSET balance = balance - amountWHERE name = 'bank';UPDATE accountSET balance = balance + amountWHERE 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 hereEXEC SQL CREATE PROCEDURE pettycash(

IN expense DECIMAL(10,2),OUT endbalance DECIMAL(10,2) )

BEGINUPDATE accountSET balance = balance - expenseWHERE name = 'bank';UPDATE accountSET balance = balance + expenseWHERE name = 'pettycash expense';

241

Page 256: Adaptive Server Anywhere

使用存储过程

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;

有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > EXECUTE 语句 [ESQL]" 和 "ASA SQL 参考手册 > SQL 语句 > PREPARE 语句 [ESQL]"。

具有结果集的存储过程具有结果集的存储过程具有结果集的存储过程具有结果集的存储过程

数据库过程也可以包含 SELECT 语句。声明该过程的方法是这样的:使

用 RESULT 子句来指定结果集中列的编号、名称和类型。结果集列与输

出参数不同。对于具有结果集的过程,在游标声明中可以使用 CALL 语句代替 SELECT 语句:

EXEC SQL BEGIN DECLARE SECTION;charhv_name[100];

EXEC SQL END DECLARE SECTION;EXEC SQL CREATE PROCEDURE female_employees()

RESULT( name char(50) )BEGIN

SELECT emp_fname || emp_lname FROM employeeWHERE 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 语句可终

止该过程的执行。

242

Page 257: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

如果在该过程中在 SELECT 语句之后还有一条语句,则不会执行该语

句。为了执行 SELECT 之后的语句,应使用 RESUME 游标名命令。

RESUME 命令可返回警告 SQLE_PROCEDURE_COMPLETE,或返回

指示存在另一游标的 SQLE_NOERROR。下面的示例阐释了一个双选择

过程:

EXEC SQL CREATE PROCEDURE people()RESULT( name char(50) )BEGIN

SELECT emp_fname || emp_lnameFROM employee;SELECT fname || lnameFROM 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 语句 " 第 222 页。

DESCRIBE 语句完全适用于过程调用。 DESCRIBE OUTPUT 生成的 SQLDA 具有每个结果集列的说明。

如果过程没有结果集,则 SQLDA 具有过程的每个 INOUT 或 OUT 参数

的说明。 DESCRIBE INPUT 语句生成的 SQLDA 具有过程的每个 IN 或 INOUT 参数的说明。

DESCRIBE ALL DESCRIBE ALL 说明 IN、 INOUT、 OUT 和 RESULT 等集合参数。

DESCRIBE ALL 使用 SQLDA 中的指示符变量提供其它信息。

243

Page 258: Adaptive Server Anywhere

使用存储过程

当说明 CALL 语句时,会在指示符变量中设置 DT_PROCEDURE_IN 和 DT_PROCEDURE_OUT 位。 DT_PROCEDURE_IN 指示 IN 或 INOUT 参数,而 DT_PROCEDURE_OUT 则指示 INOUT 或 OUT 参数。过程的 RESULT 列则清除这两个位。

在说明 OUTPUT 之后,可以使用这些位来区分具有结果集的语句 (需

要使用 OPEN、 FETCH、 RESUME 和 CLOSE)和不具有结果集的语

句 (需要使用 EXECUTE)。

有关完整说明,请参阅 "ASA SQL 参考手册 > SQL 语句 > DESCRIBE 语句 [ESQL]"。

多个结果集多个结果集多个结果集多个结果集 如果具有一个返回多个结果集的过程,则在结果集改变形状时必须在每条 RESUME 语句之后重新说明。

您需要说明游标 (而不是语句),以重新说明游标的当前位置。

244

Page 259: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

嵌入式嵌入式嵌入式嵌入式 SQL 编程技巧编程技巧编程技巧编程技巧

本节包含了一组可供嵌入式 SQL 程序开发人员使用的技巧。

实现请求管理实现请求管理实现请求管理实现请求管理

接口 DLL 的缺省行为是让应用程序在执行其它函数之前等待每个数据

库请求的完成。可以使用请求管理函数更改这一行为。例如,在使用 Interactive SQL 时,操作系统在 Interactive SQL 等待数据库响应时仍处

于活动状态,这时 Interactive SQL 可以执行一些别的任务。

通过提供 " 回调函数回调函数回调函数回调函数 ",您可以在数据库请求正在进行时完成应用程序

的活动。在此回调函数中,您不能发出除 db_cancel_request 外的其它

数据库请求。您可以在消息处理程序中使用 db_is_working 函数来确定

是否有正在进行的数据库请求。

db_register_a_callback 函数用于注册您的应用程序回调函数。

有关更多信息,请参阅以下内容:

• "db_register_a_callback 函数 " 第 259 页

• "db_cancel_request 函数 " 第 255 页

• "db_is_working 函数 " 第 258 页

备份函数备份函数备份函数备份函数

db_backup 函数在嵌入式 SQL 应用程序中提供对联机备份的支持。备

份实用程序就利用了此函数。只有在 Adaptive Server Anywhere 备份实

用程序无法满足您的备份要求时,才需要编写程序来使用此函数。

建议使用建议使用建议使用建议使用 BACKUP 语句语句语句语句

虽然此函数提供了一种给应用程序添加备份功能的方法,但是,建议您还是使用 BACKUP 语句来完成这一任务。有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > BACKUP 语句 "。

245

Page 260: Adaptive Server Anywhere

嵌入式 SQL 编程技巧

您也可以使用数据库工具 DBBackup 函数直接访问备份实用程序。有关

此函数的更多信息,请参阅 "DBBackup 函数 " 第 320 页。

有关更多信息,请参阅 "db_backup 函数 " 第 251 页。

246

Page 261: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

SQL 预处理器预处理器预处理器预处理器

SQL 预处理器会在运行编译器之前处理包含嵌入式 SQL 的 C 或 C++ 程序。

语法语法语法语法 sqlpp [ options ] SQL-filename [ output-filename ]

另请参阅另请参阅另请参阅另请参阅 " 简介 " 第 178 页

选项选项选项选项 说明说明说明说明

-c "keyword=value;…" 提供参考数据库连接参数 [UltraLite]

-d 理想数据大小

-e level 将不符合要求的 SQL 语法标记为错误

-f 将 far 关键字置于生成的静态数据上

-g 不显示 UltraLite 警告

-h line-width 限制输出的 大行长度

-k 包括 SQLCODE 的用户声明

-m version 为生成的同步脚本指定版本名称

-n 行号

-o operating-sys 目标操作系统。

-p project UltraLite 项目名称

-q 安静模式:不打印横幅

-r 生成再入式代码

-s string-len 编译器的 大字符串长度

-w level 将不符合要求的 SQL 语法标记为警告

-x 将多字节 SQL 字符串更改为转义序列

-z sequence 指定归类序列

247

Page 262: Adaptive Server Anywhere

SQL 预处理器

说明说明说明说明 SQL 预处理器会在编译器运行之前处理包含嵌入式 SQL 的 C 或 C++ 程序。 SQLPP 将 input-file 中的 SQL 语句转换为 C 语言源代码并将源代码

放入 output-file。具有嵌入式 SQL 的源程序的扩展名通常为 .sqc。缺省

的输出文件名是 SQL-filename,,,,扩展名为 .c 。如果 SQL-filename 具有 .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 统一数据库

中使用生成的同步脚本进行简单同步。

248

Page 263: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

-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 管理 " 第 207 页。

-s :设置预处理器放入 C 文件的 大大小的字符串。会使用一组符号

('a','b','c' 等)对长度大于此值的字符串进行初始化。大多数 C 编译器

都对可以处理的字符串大小有限制。此选项用于设置其上限。缺省值是 500。

-w :如果嵌入式 SQL 不是 SQL/92 的指定集合的组成部分,此选项就

会将其标记为警告。

level 的允许值及其含义如下:

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

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

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

249

Page 264: Adaptive Server Anywhere

SQL 预处理器

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

• u :标记 UltraLite 不支持的语法

• w :允许所有受支持的语法

-x :将多字节字符串更改为转义序列,以便它们可以通过编译器。

-z :此选项指定归类序列。要查看建议使用的归类序列的列表,请在

命令提示符下键入 dbinit -l。

归类序列用于帮助预处理器理解在程序源代码中使用的字符,例如,识别出适合在标识符中使用的字母字符。如果没有指定 -z,则预处理器会

尝试根据操作系统和 SQLLOCALE 环境变量确定要使用的合理归类。

250

Page 265: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

库函数参考库函数参考库函数参考库函数参考

SQL 预处理器生成对接口库或 DLL 中的函数的调用。除了 SQL 预处理

器生成的调用外,还提供了一组库函数方便数据库操作。EXEC SQL INCLUDE SQLCA 命令会包括这些函数的原型。

本节包含这些不同函数的参考说明。

DLL 入口点入口点入口点入口点 除了原型具有适合于 DLL 的修改程序外, DLL 入口点都是相同的。

您可以使用在 sqlca.h 中定义的 _esqlentry_ 以可移植方式声明入口

点。它解析为值 __stdcall:

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,

251

Page 266: Adaptive Server Anywhere

库函数参考

int file_num, unsigned long page_num, SQLDA * sqlda);

授权授权授权授权 必须连接到具有 DBA 权限或 REMOTE DBA 权限 (SQL Remote) 的用户 ID。

说明说明说明说明 建议使用建议使用建议使用建议使用 BACKUP 语句语句语句语句

虽然此函数提供了一种给应用程序添加备份功能的方法,但是建议您使用 BACKUP 语句来完成此任务。有关更多信息,请参阅 "ASA SQL 参考手册 > SQL 语句 > BACKUP 语句 "。

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

• DB_BACKUP_START :必须先调用此函数,然后才能开始备

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

忽略 file_num、 page_num 和 sqlda 参数。

• 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_num 和 sqlda 参数。

• DB_BACKUP_READ_PAGE :读取由 file_num 指定的数据库文

件的一页。使用 DB_BACKUP_OPEN_FILE 操作对 db_backup 调用成功后会在 SQLCOUNT 中返回一个页数, page_num 值应介于

252

Page 267: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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。

253

Page 268: Adaptive Server Anywhere

库函数参考

此后,您不应再次调用 db_backup (除非要关闭文件并完成备

份),否则,您会获得备份日志文件的第二份副本并收到 SQLE_NOTFOUND。

• DB_BACKUP_CLOSE_FILE :处理完一个文件后必须调用此函

数以关闭由 file_num 指定的数据库文件。

忽略 page_num 和 sqlda 参数。

• DB_BACKUP_END :备份结束时必须调用此函数。在此备份结

束之前,任何其它备份都无法启动。会再次启用检查点。

忽略 file_num、 page_num 和 sqlda 参数。

dbbackup 程序使用下面的算法。请注意,这不是 C 代码,也不包括错

误检查。

db_backup( ... DB_BACKUP_START ... )allocate page buffer based on page size in SQLCODEsqlda = alloc_sqlda( 1 )sqlda->sqld = 1;sqlda->sqlvar[0].sqltype = DT_BINARYsqlda->sqlvar[0].sqldata = allocated bufferfor 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 ifnext file_numbackup up file DB_BACKUP_WRITE_FILE as abovebackup up file DB_BACKUP_TRANS_LOG_FILE as abovefree page bufferdb_backup( ... DB_BACKUP_END ... )

254

Page 269: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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 函数 " 第 251 页中的 DB_BACKUP_READ_RENAME_LOG)之后使用它来删除旧事务日

志。您必须连接到具有 DBA 权限的用户 ID。

255

Page 270: Adaptive Server Anywhere

库函数参考

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 的信息,请参阅 "UltraLite 用户

指南 > 嵌入式 SQL 接口 > db_fini 函数 "。

256

Page 271: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

db_get_property 函数函数函数函数

原型原型原型原型 unsigned int db_get_property( SQLCA * sqlca, a_db_property property, char * value_buffer, int value_buffer_size );

说明说明说明说明 此函数用于获得您当前连接到的服务器的地址。 dbping 实用程序使用

它来显示输出服务器地址。

也可以使用此函数获得数据库属性的值。如 "ASA 数据库管理指南 > 数据库性能和连接属性 > 数据库属性 " 中所述,也可以通过执行 SELECT 语句以独立于接口的方式获得数据库属性。

参数如下:

• a_db_property :具有值 DB_PROP_SERVER_ADDRESS 的 enum。 DB_PROP_SERVER_ADDRESS 获取当前连接的服务器网

络地址,作为可打印字符串。共享内存和 NamedPipes 协议始终会

为地址返回空字符串。 TCP/IP 和 SPX 协议会返回非空字符串地

址。

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

值。

• value_buffer_size :字符串 value_buffer 的 大长度,其中包括

终止的空字符。

另请参阅另请参阅另请参阅另请参阅 "ASA 数据库管理指南 > 数据库性能和连接属性 > 数据库属性 "

db_init 函数函数函数函数

原型原型原型原型 unsigned short db_init( SQLCA *sqlca );

说明说明说明说明 此函数初始化数据库接口库。在进行任何其它库调用之前和执行任何嵌入式 SQL 命令之前,都必须调用此函数。在进行此调用时将分配和初

始化接口库对您的程序所要求的资源。

257

Page 272: Adaptive Server Anywhere

库函数参考

在程序结尾处使用 db_fini 来释放资源。如果在处理过程中出现错误,

则在 SQLCA 中返回这些错误且返回 0。如果没有错误,则返回非零

值,您就可以开始使用嵌入式 SQL 命令和函数。

在大多数情况下,此函数只应调用一次 (传递在 sqlca.h 头文件中定

义的全局 sqlca 变量的地址)。如果您要使用嵌入式 SQL 来编写具有多

个线程的 DLL 或应用程序,则每使用一个 SQLCA,就要调用一次 db_init。

有关更多信息,请参阅 " 多线程代码或再入式代码的 SQLCA 管理 " 第207 页。

警告警告警告警告在 NetWare 上如未能为每个 db_init 调用 db_fini,则会导致数据库服务

器和 NetWare 文件服务器出现故障。

另请参阅另请参阅另请参阅另请参阅 有关在 UltraLite 应用程序中使用 db_init 的信息,请参阅 "UltraLite 用户

指南 > 嵌入式 SQL 接口 > 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 );

258

Page 273: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

说明说明说明说明 提供对 dblocate 实用程序所显示的信息的编程式访问,列出本地网络

上正在监听 TCP/IP 的所有 Adaptive Server Anywhere 数据库服务器。

回调函数必须具有以下原型:

int (*)( SQLCA *sqlca, a_server_address *server_addr, void *callback_user_data );

对于找到的每台服务器都要调用回调函数。如果回调函数返回 0,则 db_locate_servers 停止迭代通过服务器。

传递到回调函数的 sqlca 和 callback_user_data 是那些传递到 db_locate_servers 中的函数。第二个参数是指向 a_server_address 结构的指针。 a_server_address 是在 sqlca.h 中定义的,所使用的定义

如下:

typedef struct a_server_address { a_SQL_uint32port_type; a_SQL_uint32port_num; char *name; char *address;} a_server_address;

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

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

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

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

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > Server Location 实用程序 "。

db_register_a_callback 函数函数函数函数

原型原型原型原型 void db_register_a_callback( SQLCA *sqlca, a_db_callback_index index, ( SQL_CALLBACK_PARM ) callback );

259

Page 274: Adaptive Server Anywhere

库函数参考

说明说明说明说明 此函数注册回调函数。

如果您不注册 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 值。

260

Page 275: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

• DB_CALLBACK_WAIT :原型如下:

void SQL_CALLBACK wait_callback( SQLCA *sqlca );

在数据库服务器或 Client Library 忙于处理您的数据库请求的同

时,接口库反复调用此函数。

您可以按如下所示注册此回调函数:

db_register_a_callback( &sqlca, DBCALLBACK_WAIT, (SQL_CALLBACK_PARM)&db_wait_request );

• DB_CALLBACK_MESSAGE :使用此函数后,应用程序可以对

处理请求期间从服务器接收的消息进行处理。

回调原型如下:

void SQL_CALLBACK message_callback( SQLCA* sqlca, unsigned short msg_type, an_SQL_code code, unsigned 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 等类型的消息会以与操作系统相关的

方式更为突出地显示。

261

Page 276: Adaptive Server Anywhere

库函数参考

db_start_database 函数函数函数函数

原型原型原型原型 unsigned int db_start_database( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,其中包含以分号分隔的参数设置列表,

每个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

有关可用连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接参数和

通信参数 > 连接参数 "。

说明说明说明说明 如果数据库尚未运行,则在现有服务器上启动数据库。在 "ASA 数据库

管理指南 > 连接到数据库 > 启动个人服务器 " 一节中说明了启动数据库

时执行的步骤。

如果数据库已经运行或成功地启动了它,则返回值为真。错误消息在 SQLCA. 中返回

如果在参数中提供了用户 ID 和口令,则它们将被忽略。

启动和停止数据库所需的权限在服务器命令行上设置。有关信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > 数据库服务器 "。

db_start_engine 函数函数函数函数

原型原型原型原型 unsigned int db_start_engine( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,包含以分号分隔的参数设置列表,每

个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

262

Page 277: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

有关可供使用的连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接

参数和通信参数 > 连接参数 "。

说明说明说明说明 如果数据库服务器没有运行则启动它。此函数执行的步骤就是 "ASA 数据库管理指南 > 连接到数据库 > 启动个人服务器 " 中列出的那些步骤。

如果已经找到或成功启动数据库服务器,则返回值为真。错误消息在 SQLCA 中返回。

下面对 db_start_engine 的调用会启动数据库服务器并将其命名为 asademo,虽然使用了 DBF 连接参数,但不会装载数据库:

db_start_engine( &sqlca, "DBF=c:\\asa8\\asademo.db; Start=dbeng8" );

如果您希望既启动服务器也启动数据库,请在 START 连接参数中包括

数据库文件:

db_start_engine( &sqlca,"ENG=eng_name;START=dbeng8 c:\\asa\\asademo.db" );

此调用启动服务器,将其命名为 eng_name,并启动该服务器上的 asademo 数据库。

db_start_engine 函数在尝试启动某个服务器之前会先尝试连接到它,以

免出现试图启动已在运行的服务器的情况。

FORCESTART 连接参数仅由 db_start_engine 函数使用。当设置为 YES 时,在尝试启动服务器之前不尝试连接到服务器。这样,下面的一对命令就能够按预期方式工作:

1. 启动名为 server_1 的数据库服务器:

start dbeng8 -n server_1 asademo.db

2. 强制启动一台新服务器并连接到它:

db_start_engine( &sqlda, "START=dbeng8 -n server_2 asademo.db;ForceStart=YES" )

如果没有使用 FORCESTART,而且没有使用 ENG 参数,则第二个命令

会尝试连接到 server_1。 db_start_engine 函数不能从 START 参数的 -n 选项获取服务器名。

263

Page 278: Adaptive Server Anywhere

库函数参考

db_stop_database 函数函数函数函数

原型原型原型原型 unsigned int db_stop_database( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,其中包含以分号分隔的参数设置列表,

每个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

有关可用连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接参数和

通信参数 > 连接参数 "。

说明说明说明说明 在由 EngineName 标识的服务器上停止由 DatabaseName 标识的数据

库。如果未指定 EngineName,则使用缺省的服务器。

缺省情况下,此函数不停止有现有连接的数据库。如果 Unconditional 为 yes,则不管是否有现有连接都会停止数据库。

返回值 TRUE 指示没有错误。

启动和停止数据库所需的权限在服务器命令行上设置。有关信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > 数据库服务器 "。

db_stop_engine 函数函数函数函数

原型原型原型原型 unsigned int db_stop_engine( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,其中包含以分号分隔的参数设置列表,

每个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

有关可用连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接参数和

通信参数 > 连接参数 "。

264

Page 279: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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

• 查找具有与 EngineName 参数匹配的名称的本地数据库服务器。

如果未指定 EngineName,则查找缺省的本地数据库服务器。

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

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

据库。

• 卸载数据库服务器。

缺省情况下,此函数不停止有现有连接的数据库。如果 Unconditional 为 yes,则不管是否有现有连接都会停止数据库。

C 程序可以使用此函数,而不用衍生 DBSTOP。返回值 TRUE 指示没有

错误。

是否可以使用 db_stop_engine 取决于在 -gk 服务器选项上设置的权限。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > -gk 服务器选项 "。

db_string_connect 函数函数函数函数

原型原型原型原型 unsigned int db_string_connect( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,其中包含以分号分隔的参数设置列表,

每个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

有关可用连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接参数和

通信参数 > 连接参数 "。

说明说明说明说明 提供了 SQL CONNECT 命令所具有的功能以外的其它功能。此函数使

用在 "ASA 数据库管理指南 > 连接到数据库 > 对连接进行疑难解答 " 中说明的算法执行连接。

265

Page 280: Adaptive Server Anywhere

库函数参考

如果成功建立连接则返回值为真 (非零),否则返回值为假 (零)。有关启动服务器、启动数据库或进行连接的错误消息均在 SQLCA 中返

回。

db_string_disconnect 函数函数函数函数

原型原型原型原型 unsigned int db_string_disconnect( SQLCA * sqlca, char * parms );

参数参数参数参数 sqlca :指向 SQLCA 结构的指针。有关信息,请参阅 "SQL 通信区域 (SQLCA)" 第 204 页。

parms :以空值终止的字符串,其中包含以分号分隔的参数设置列表,

每个参数设置的形式均为 KEYWORD=value。例如,

"UID=DBA;PWD=SQL;DBF=c:\\db\\mydatabase.db"

有关可用连接参数的列表,请参阅 "ASA 数据库管理指南 > 连接参数和

通信参数 > 连接参数 "。

说明说明说明说明 此函数断开由 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 是一个常规连接字符串,它可能包含服务器和数据库信

息,也可能不包含。

266

Page 281: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

如果 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 分配的任何

描述符都被释放。

267

Page 282: Adaptive Server Anywhere

库函数参考

free_sqlda 函数函数函数函数

原型原型原型原型 void free_sqlda( struct sqlda * sqlda );

说明说明说明说明 释放分配给此 sqlda 的空间并释放指示符变量空间,这些空间是在 fill_sqlda 中分配的。不释放由每个 sqldata 指针引用的内存。

free_sqlda_noind 函数函数函数函数

原型原型原型原型 void free_sqlda_noind( struct sqlda * sqlda );

说明说明说明说明 释放分配给此 sqlda 的空间。不释放由每个 sqldata 指针引用的内存。

将忽略指示符变量指针。

"ASA 数据库管理指南 > 数据库性能和连接属性 > 数据库属性 "

"ASA 数据库管理指南 > 数据库管理实用程序 > 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,则此测

试不能确定是否需要引号。

268

Page 283: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

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。

269

Page 284: Adaptive Server Anywhere

嵌入式 SQL 命令汇总

嵌入式嵌入式嵌入式嵌入式 SQL 命令汇总命令汇总命令汇总命令汇总

EXEC SQL 所有嵌入式 SQL 语句都必须以 EXEC SQL 开头且以分号 (;) 结尾。

有两组嵌入式 SQL 命令。标准 SQL 命令的用法是:只需将其置于 C 程序中,并在其前后分别加上 EXEC SQL 和分号 (;) 即可。 CONNECT、DELETE、 SELECT、 SET 和 UPDATE 有一些附加格式只能在嵌入式 SQL 中使用。具有这些格式的命令属于特定于嵌入式 SQL 的命令的第

二个类别。

有关标准 SQL 命令的说明,请参阅 "ASA SQL 参考手册 > SQL 语句 "。

有几个 SQL 命令是特定于嵌入式 SQL 的并只能在 C 程序中使用。

有关这些嵌入式 SQL 命令的更多信息,请参阅 "ASA SQL 参考手册 > SQL 语言元素 "。

可以从嵌入式 SQL 应用程序使用标准的数据操纵语句和数据定义语句。

另外,下列语句也是专用于嵌入式 SQL 编程的语句:

• ALLOCATE DESCRIPTOR :为描述符分配内存

请参阅 "ASA SQL 参考手册 > SQL 语句 > ALLOCATE DESCRIPTOR 语句 [ESQL]"

• CLOSE :关闭游标

请参阅 "ASA SQL 参考手册 > SQL 语句 > CLOSE 语句 [ESQL] [SP]"

• CONNECT :连接到数据库

请参阅 "ASA SQL 参考手册 > SQL 语句 > CONNECT 语句 [ESQL] [Interactive SQL]"

• DEALLOCATE DESCRIPTOR :为描述符回收内存

请参阅 "ASA SQL 参考手册 > SQL 语句 > DEALLOCATE DESCRIPTOR 语句 [ESQL]"

270

Page 285: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

• Declaration Section :为数据库通信声明主机变量

请参阅 "ASA SQL 参考手册 > SQL 语句 > 声明部分 [ESQL]"

• DECLARE CURSOR :声明游标

请参阅 "ASA SQL 参考手册 > SQL 语句 > DECLARE CURSOR 语句 [ESQL] [SP]"

• DELETE (已定位)(已定位)(已定位)(已定位) :删除游标中当前位置的行

请参阅 "ASA SQL 参考手册 > SQL 语句 > DELETE (定位)语句 [ESQL] [SP]"

• DESCRIBE :说明特定 SQL 语句的主机变量

请参阅 "ASA SQL 参考手册 > SQL 语句 > DESCRIBE 语句 [ESQL]"

• DISCONNECT :从数据库服务器断开连接

请参阅 "ASA SQL 参考手册 > SQL 语句 > DISCONNECT 语句 [ESQL] [Interactive SQL]"

• DROP STATEMENT :释放准备的语句所使用的资源

请参阅 "ASA SQL 参考手册 > SQL 语句 > DROP STATEMENT 语句 [ESQL]"

• EXECUTE :执行特定的 SQL 语句

请参阅 "ASA SQL 参考手册 > SQL 语句 > EXECUTE 语句 [ESQL]"

• EXPLAIN :解释特定游标的优化策略

请参阅 "ASA SQL 参考手册 > SQL 语句 > EXPLAIN 语句 [ESQL]"

• FETCH :从游标读取行

请参阅 "ASA SQL 参考手册 > SQL 语句 > FETCH 语句 [ESQL] [SP]"

• GET DATA :从游标读取 Long 型值

271

Page 286: Adaptive Server Anywhere

嵌入式 SQL 命令汇总

请参阅 "ASA SQL 参考手册 > SQL 语句 > GET DATA 语句 [ESQL]"

• GET DESCRIPTOR :检索有关 SQLDA 中变量的信息。

请参阅 "ASA SQL 参考手册 > SQL 语句 > GET DESCRIPTOR 语句 [ESQL]"

• GET OPTION :获得特定数据库选项的设置

请参阅 "ASA SQL 参考手册 > SQL 语句 > GET OPTION 语句 [ESQL]"

• INCLUDE :包括要进行 SQL 预处理的文件

请参阅 "ASA SQL 参考手册 > SQL 语句 > INCLUDE 语句 [ESQL]"

• OPEN :打开游标

请参阅 "ASA SQL 参考手册 > SQL 语句 > OPEN 语句 [ESQL] [SP]"

• PREPARE :准备特定的 SQL 语句

请参阅 "ASA SQL 参考手册 > SQL 语句 > PREPARE 语句 [ESQL]"

• PUT :向游标中插入行

请参阅 "ASA SQL 参考手册 > SQL 语句 > PUT 语句 [ESQL]"

• SET CONNECTION :更改活动连接

请参阅 "ASA SQL 参考手册 > SQL 语句 > SET CONNECTION 语句 [Interactive SQL] [ESQL]"

• SET DESCRIPTOR :说明 SQLDA 中的变量并将数据置于 SQLDA 中

请参阅 "ASA SQL 参考手册 > SQL 语句 > SET DESCRIPTOR 语句 [ESQL]"

• SET SQLCA :使用一个 SQLCA (非缺省全局 SQLCA)

272

Page 287: Adaptive Server Anywhere

第 6 章 嵌入式 SQL 编程

请参阅 "ASA SQL 参考手册 > SQL 语句 > SET SQLCA 语句 [ESQL]"

• UPDATE (已定位)(已定位)(已定位)(已定位) :在游标的当前位置更新行

请参阅 "ASA SQL 参考手册 > SQL 语句 > UPDATE (定位)语句 [ESQL] [SP]"

• WHENEVER :指定 SQL 语句中出现错误时要采取的操作

请参阅 "ASA SQL 参考手册 > SQL 语句 > WHENEVER 语句 [ESQL]"

273

Page 288: Adaptive Server Anywhere

嵌入式 SQL 命令汇总

274

Page 289: Adaptive Server Anywhere

第 7 章

ODBC 编程编程编程编程

关于本章关于本章关于本章关于本章 本章讲述有关开发那些直接调用 ODBC 编程接口的应用程序的信息。

有关 ODBC 应用程序开发的主要文档是 Microsoft ODBC SDK 文档,该

文档是作为 Microsoft 数据访问组件 (MDAC) SDK 的一部分提供的。本

章提供的是基础材料,描述的是特定于 Adaptive Server Anywhere 的功

能,而不是 ODBC 应用程序编程的详尽指南。

有些已经具有 ODBC 支持的应用程序开发工具提供了它们自己的编程

接口,这类接口隐藏了 ODBC 接口。本章不适用于这些工具的用户。

275

Page 290: Adaptive Server Anywhere

ODBC 简介

ODBC 简介简介简介简介

" 开放式数据库连接开放式数据库连接开放式数据库连接开放式数据库连接 "(ODBC) 接口是一个应用程序编程接口,由 Microsoft Corporation 定义为 Windows 操作系统上到数据库管理系统的

标准接口。 ODBC 是基于调用的接口。

为编写用于 Adaptive Server Anywhere 的 ODBC 应用程序,您需要:

• Adaptive Server Anywhere。

• 能够为您的环境创建程序的 C 编译器。

• Microsoft ODBC 软件开发工具包。在 Microsoft 开发人员网络上可

以找到该工具包;该工具包提供测试 ODBC 应用程序时所用的文

档和其它工具。

支持的平台支持的平台支持的平台支持的平台 除了支持 Windows 上的 ODBC API 之外, Adaptive Server Anywhere 还支持 UNIX 上和 Windows CE 上的 ODBC API。由于有了多平台 ODBC 支持,便携式数据库应用程序开发变得更加容易。

有关在分布式事务征用 ODBC 驱动程序的信息,请参阅 "" 三层计算和

分布式事务 " 第 397 页 "。

对对对对 ODBC 的支持的支持的支持的支持

Adaptive Server Anywhere 支持 ODBC 3.52。

ODBC 支持的级别支持的级别支持的级别支持的级别 ODBC 功能是根据支持的级别来组织的。这些功能为 " 核心核心核心核心 "、 " 级别级别级别级别 1"或 "级别级别级别级别 2","级别级别级别级别 2"是 ODBC 支持的 完整级别。《ODBC 程序员参

考》中介绍了这些功能,这些功能由 Microsoft Corporation 作为 ODBC 软件开发工具包的一部分提供,也可以从 Microsoft Web 站点获取,网

址是 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcabout_this_manual.asp。

Adaptive Server Anywhere 支持的功支持的功支持的功支持的功

能能能能

Adaptive Server Anywhere 支持 ODBC 3.52 规范。

• 核心支持核心支持核心支持核心支持 Adaptive Server Anywhere 支持所有 " 核心 " 级别功能。

276

Page 291: Adaptive Server Anywhere

第 7 章 ODBC 编程

• 级别级别级别级别 1 支持支持支持支持 Adaptive Server Anywhere 支持所有 " 级别 1" 功能,

ODBC 函数的异步执行除外。

Adaptive Server Anywhere 支持多线程共享一个连接。来自不同线

程的请求被 Adaptive Server Anywhere 序列化。

• 级别级别级别级别 2 支持支持支持支持 Adaptive Server Anywhere 支持除以下几项以外的所

有其它 " 级别 2" 功能:

• 表和视图的由三部分构成的名称。这不适用于 Adaptive Server Anywhere。

• 指定的个别语句的 ODBC 函数异步执行。

• 使登录请求和 SQL 查询超时的能力。

ODBC 向后兼容向后兼容向后兼容向后兼容 使用旧版本 ODBC 开发的应用程序能继续与 Adaptive Server Anywhere 和更新版本的 "ODBC 驱动程序管理器 " 一起工作。新的 ODBC 功能不

能用于较旧的应用程序。

ODBC 驱动程序管驱动程序管驱动程序管驱动程序管

理器理器理器理器

"ODBC 驱动程序管理器 " 是与 Adaptive Server Anywhere 一起提供的 ODBC 软件的一部分。"ODBC 版本 3 驱动程序管理器 " 有一个用于配置 ODBC 数据源的新接口。

277

Page 292: Adaptive Server Anywhere

创建 ODBC 应用程序

创建创建创建创建 ODBC 应用程序应用程序应用程序应用程序

本节介绍如何编译和链接简单的 ODBC 应用程序。

包括包括包括包括 ODBC 头文件头文件头文件头文件

每个调用 ODBC 函数的 C 源文件都必须包括一个平台特定的 ODBC 头文件。每个平台特定的头文件都包括主要的 ODBC 头文件 odbc.h,该

头文件定义编写 ODBC 程序所需的所有函数、数据类型和常量定义。

❖ 将将将将 ODBC 头文件包括在头文件包括在头文件包括在头文件包括在 C 源文件中:源文件中:源文件中:源文件中:

1 给您的源文件添加 include 行,该行引用相应的特定于平台的头

文件。要使用的行如下所示:

2 将包含头文件的目录添加到您的编译器的包括路径中。

平台特定的头文件和 odbc.h 都安装在 SQL Anywhere 目录的 h 子目录中。

在在在在 Windows 上链接上链接上链接上链接 ODBC 应用程序应用程序应用程序应用程序

本节不适用于 Windows CE。有关更多信息,请参阅 "" 在 Windows CE 上链接 ODBC 应用程序 " 第 279 页 "。

链接您的应用程序时,必须链接到适当的导入库文件才能访问 ODBC 函数。导入库为 "ODBC 驱动程序管理器 "odbc32.dll 定义入口点, "驱动程序管理器 " 进而装载 Adaptive Server Anywhere ODBC 驱动程序 dbodbc8.dll。

操作系统操作系统操作系统操作系统 Include 行行行行

Windows #include "ntodbc.h"

UNIX #include "unixodbc.h"

Windows CE #include "ntodbc.h"

278

Page 293: Adaptive Server Anywhere

第 7 章 ODBC 编程

针对 Microsoft、 Watcom 和 Borland 编译器,提供的导入库各不相同。

❖ 链接链接链接链接 ODBC 应用程序应用程序应用程序应用程序 (Windows)::::

• 将包含平台特定的导入库的目录添加到库目录列表。

导入库存储在 Adaptive Server Anywhere 可执行文件所在目录的 lib 子目录中,名称如下:

在在在在 Windows CE 上链接上链接上链接上链接 ODBC 应用程序应用程序应用程序应用程序

在 Windows CE 操作系统上没有 "ODBC 驱动程序管理器 "。导入库 (dbodbc8.lib) 定义直接到 Adaptive Server Anywhere ODBC 驱动程序 dbodbc8.dll 的入口点。

针对那些支持 Windows CE 的各种不同芯片,提供的这个 DLL 的版本也

各不相同。这些文件位于您的 SQL Anywhere 目录中 ce 目录的操作系

统特定的子目录中。例如,用于在 SH3 芯片上使用的 Windows CE 的 ODBC 驱动程序位于以下位置:

C:\Program Files\Sybase\SQL Anywhere 8\ce\SH3

有关支持的 Windows CE 版本列表,请参阅 "SQL Anywhere Studio 介绍 > 教程:使用 InfoMaker 创建报告 > 支持 Adaptive Server Anywhere 的操

作系统 "。

❖ 链接链接链接链接 ODBC 应用程序应用程序应用程序应用程序 (Windows CE)::::

1 将包含平台特定的导入库的目录添加到库目录列表。

操作系统操作系统操作系统操作系统 编译器编译器编译器编译器 导入库导入库导入库导入库

Windows Microsoft odbc32.lib

Windows Watcom C/C++ wodbc32.lib

Windows Borland bodbc32.lib

Windows CE Microsoft dbodbc8.lib

279

Page 294: Adaptive Server Anywhere

创建 ODBC 应用程序

导入库名称为 dbodbc8.lib,存储在您的 SQL Anywhere 目录

中 ce 目录下操作系统特定的位置。例如,用于在 SH3 芯片上

使用的 Windows CE 的导入库位于以下位置:

C:\Program Files\Sybase\SQL Anywhere 8\ce\SH3\lib

2 在提供给 SQLDriverConnect 函数的连接字符串中指定 DRIVER= 参数。

szConnStrIn = "driver=ospath\dbodbc8.dll;dbf=c:\asademo.db"

其中 ospath 是 Windows CE 设备上 SQL Anywhere 目录的芯片

特定子目录的完整路径。例如:

\Program Files\Sybase\SQL Anywhere 8\ce\SH3\lib

示例程序 (odbc.c) 使用一个名为 ASA 8.0 Sample.dsn 的 " 文件 " 数据源 (FileDSN 连接参数)。您可以在台式机系统上从 "ODBC 驱动程

序管理器 " 创建 " 文件 " 数据源,然后将它们复制到 Windows CE 设备

上。

Windows CE 和和和和 Unicode

Adaptive Server Anywhere 使用大家称为 UTF-8 的编码方式,这是一种

多字节字符编码技术,可用于进行 Unicode 编码。

Adaptive Server Anywhere ODBC 驱动程序支持 ASCII (8 位)字符串,

也支持 Unicode 代码 (宽字符)字符串。 UNICODE 宏控制 ODBC 函数将使用 ASCII 还是 Unicode 字符串。如果创建应用程序时必须定义 UNICODE 宏,而您又要使用 ASCII ODBC 函数,就还必须定义 SQL_NOUNICODEMAP 宏。

Samples\ASA\C\odbc.c 示例文件说明了如何使用 Unicode ODBC 功能。

在在在在 UNIX 上链接上链接上链接上链接 ODBC 应用程序应用程序应用程序应用程序

Adaptive Server Anywhere 中未附带 "ODBC 驱动程序管理器 ",但是有

第三方 " 驱动程序管理器 " 可供使用。本节说明如何创建不使用

"ODBC 驱动程序管理器 " 的 ODBC 应用程序。

280

Page 295: Adaptive Server Anywhere

第 7 章 ODBC 编程

ODBC 驱动程序驱动程序驱动程序驱动程序 ODBC 驱动程序是一个共享对象或者共享库。针对单线程应用程序和多

线程应用程序,提供的 Adaptive Server Anywhere ODBC 驱动程序的版

本是不同的。

ODBC 驱动程序就是下面的文件:

库是作为符号链接安装的,这些链接指向带有版本号 (在括号中)的共享库。

❖ 链接链接链接链接 ODBC 应用程序应用程序应用程序应用程序 (UNIX)::::

1 将您的应用程序直接链接到适当的 ODBC 驱动程序。

2 部署您的应用程序时,确保用户的库路径中有适当的 ODBC 驱动程序。

数据源信息数据源信息数据源信息数据源信息 如果 Adaptive Server Anywhere 未检测到 "ODBC 驱动程序管理器 ",它

将在 ~/.odbc.ini 中寻找数据源信息。

在在在在 UNIX 上使用上使用上使用上使用 "ODBC 驱动程序管理器驱动程序管理器驱动程序管理器驱动程序管理器 "

用户可以获得为 UNIX 提供的第三方 "ODBC 驱动程序管理器 "。"ODBC 驱动程序管理器 " 包括下列文件:

操作系统操作系统操作系统操作系统 线程模型线程模型线程模型线程模型 ODBC 驱动程序驱动程序驱动程序驱动程序

Solaris/Sparc 单线程 dbodbc8.so (dbodbc8.so.1)

Solaris/Sparc 多线程 dbodbc_r.so (dbodbc_r.so.1)

操作系统操作系统操作系统操作系统 文件文件文件文件

Solaris/Sparc libodbc.so (libodbc.so.1)libodbcinst.so (libodbcinst.so.1)

Solaris/Sparc libodbc.so (libodbc.so.1)libodbcinst.so (libodbcinst.so.1)

281

Page 296: Adaptive Server Anywhere

创建 ODBC 应用程序

如果您正在部署的应用程序需要 "ODBC 驱动程序管理器 ",而且您没

有使用第三方 " 驱动程序管理器 ",请为 libodbc 和 libodbcinst 共享库创建指向 Adaptive Server Anywhere ODBC 驱动程序的符号链接。

如果存在 "ODBC 驱动程序管理器 ",则 Adaptive Server Anywhere 会向

" 驱动程序管理器 " (而非 ~/.odbc.ini)查询数据源信息。

标准的 ODBC 应用程序并不直接链接到 ODBC 驱动程序,而需要通过

"ODBC 驱动程序管理器 " 进行 ODBC 函数调用。在 UNIX 和 Windows CE 操作系统上, Adaptive Server Anywhere 中未附带 "ODBC 驱动程序

管理器 "。您仍然可以通过直接链接到 Adaptive Server Anywhere ODBC 驱动程序来创建 ODBC 应用程序,但是那样您将只能访问 Adaptive Server Anywhere 数据源。

282

Page 297: Adaptive Server Anywhere

第 7 章 ODBC 编程

ODBC 示例示例示例示例

Adaptive Server Anywhere 中附带了几个 ODBC 示例。您可以在 SQL Anywhere 目录的 Samples\ASA 子目录中找到这些示例。缺省情况

下,路径为:

C:\Program Files\Sybase\SQL Anywhere 8\Samples\ASA

目录中这些以 ODBC 开头的示例分别说明不同的、简单的 ODBC 任务,

例如连接到一个数据库和执行一些语句等。提供的完整示例 ODBC 程序为 Samples\ASA\C\odbc.c。该程序执行的操作与同一目录中嵌入式 SQL 动态游标示例程序执行的操作相同。

有关该关联的嵌入式 SQL 程序的信息,请参阅 "" 示例嵌入式 SQL 程序

" 第 186 页 "。

创建示例创建示例创建示例创建示例 ODBC 程序程序程序程序

Samples\ASA\C 中的 ODBC 示例程序包括一个批处理文件 (对于 UNIX 是 shell 脚本),可以用来编译和链接示例应用程序。

❖ 创建示例创建示例创建示例创建示例 ODBC 程序:程序:程序:程序:

1 打开命令提示符,将目录改为 SQL Anywhere 目录的 Samples\ASA\C 子目录。

2 运行 makeall 批处理文件或 shell 脚本

命令的格式如下:

makeall api platform compiler

参数如下:

• API 指定 odbc 来编译 ODBC 示例,而不是编译应用程序

的嵌入式 SQL 版本。

• Platform 指定 WINNT 针对 Windows 操作系统进行编译。

283

Page 298: Adaptive Server Anywhere

ODBC 示例

• Compiler 指定用来编译程序的编译器。编译器可以是下列

任一工具:

• WC 使用 Watcom C/C++

• MC 使用 Microsoft Visual C++

• BC 使用 Borland C++ Builder

运行示例运行示例运行示例运行示例 ODBC 程序程序程序程序

在为支持服务的 Windows 版本编译示例程序 odbc.c 时,可以选择让该

示例程序作为服务运行。

两个包含 Windows 服务的示例代码的文件为源文件 ntsvc.c 和头文件 ntsvc.h。这些代码允许链接的可执行文件或者作为常规可执行文件运

行,或者作为 Windows 服务运行。

❖ 运行运行运行运行 ODBC 示例:示例:示例:示例:

1 启动该程序:

• 运行文件 Samples\ASA\C\odbcwnt.exe。

2 选择表:

• 选择示例数据库中的一个表。例如,您可以输入 Customer

或者 Employee。

284

Page 299: Adaptive Server Anywhere

第 7 章 ODBC 编程

❖ 将将将将 ODBC 示例作为示例作为示例作为示例作为 Windows 服务运行:服务运行:服务运行:服务运行:

1 启动 Sybase Central,打开 " 服务 " 文件夹。

2 单击 " 添加服务 "。按照将示例程序作为服务添加的有关说明

进行操作。

3 右击服务图标,单击 " 启动 " 以启动该服务。

在作为服务运行时,如果可能,程序会显示正常的用户界面。它还会将输出写入 " 应用程序事件日志 "。如果不能启动用户界面,该程序将在

" 应用程序事件日志 " 中记录一页数据,然后会停止。

285

Page 300: Adaptive Server Anywhere

ODBC 句柄

ODBC 句柄句柄句柄句柄

ODBC 应用程序使用一小组 " 句柄句柄句柄句柄 " 来定义基本的功能,例如数据库连

接和 SQL 语句。句柄是一个 32 位值。

下面的句柄基本上用于所有 ODBC 应用程序。

• 环境环境环境环境 环境句柄提供一个在其中访问数据的全局上下文。每个 ODBC 应用程序必须在启动时分配一个 (不多不少)环境句柄,

在结束时必须将其释放。

下面的代码说明如何分配环境句柄:

SQLHENV env;SQLRETURN rc;rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL _NULL_HANDLE, &env );

• 连接连接连接连接 连接是由 ODBC 驱动程序和数据源指定的。应用程序可以

具有几个与它的环境相关联的连接。分配连接句柄并不会建立连接;必须首先分配连接句柄,然后才能在建立连接时使用它。

下面的代码说明如何分配连接句柄:

SQLHDBC dbc;SQLRETURN rc;rc = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );

• 语句语句语句语句 语句句柄提供到 SQL 语句的访问,以及与之相关联的任何

信息,例如结果集和参数。每个连接可以有多个语句。在游标操作 (读取数据)和单个语句执行 (例如, INSERT、 UPDATE 和 DELETE)中都使用语句。

下面的代码说明如何分配语句句柄:

SQLHSTMT stmt;SQLRETURN rc;rc = SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );

286

Page 301: Adaptive Server Anywhere

第 7 章 ODBC 编程

分配分配分配分配 ODBC 句柄句柄句柄句柄

ODBC 程序所需的句柄类型现列示如下:

❖ 使用使用使用使用 ODBC 句柄:句柄:句柄:句柄:

1 调用 SQLAllocHandle 函数。

SQLAllocHandle 采用以下参数:

• 要分配的项所属类型的标识符

• 父项的句柄

• 指向要分配的句柄所在位置的指针

有关详细说明,请参阅 《Microsoft ODBC 程序员参

考》中的 "SQLAllocHandle"。

2 在随后的函数调用中使用该句柄。

3 使用 SQLFreeHandle 释放对象。

SQLFreeHandle 采用下列参数:

• 要释放的项所属类型的标识符

• 要释放的项的句柄

有关详细说明,请参阅 《Microsoft ODBC 程序员参

考》中的 "SQLFreeHandle"。

项项项项 句柄类型句柄类型句柄类型句柄类型

环境 SQLHENV

连接 SQLHDBC

语句 SQLHSTMT

描述符 SQLHDESC

287

Page 302: Adaptive Server Anywhere

ODBC 句柄

示例示例示例示例 下面的代码段将分配和释放一个环境句柄:

SQLHENV env;SQLRETURN retcode;retcode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO ) { // success: application code here}SQLFreeHandle( SQL_HANDLE_ENV, env );

有关返回代码和错误句柄的更多信息,请参阅 "" 处理错误 " 第 306 页

"。

第一个第一个第一个第一个 ODBC 示例示例示例示例

下面是一个示例 ODBC 程序,该程序连接到 Adaptive Server Anywhere 示例数据库,然后立即断开了连接。

您可以在 SQL Anywhere 目录中找到此示例,即 Samples\ASA\ODBCConnect\odbcconnect.cpp。

#include <stdio.h>#include "ntodbc.h"int main(int argc, char* argv[]){ SQLHENV env; SQLHDBC dbc; SQLRETURN retcode; retcode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env ); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { printf( "env allocated\n" ); /* Set the ODBC version environment attribute */ retcode = SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); retcode = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc ); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { printf( "dbc allocated\n" ); retcode = SQLConnect( dbc,

288

Page 303: Adaptive Server Anywhere

第 7 章 ODBC 编程

(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS, (SQLCHAR* ) "DBA", SQL_NTS, (SQLCHAR*) "SQL", SQL_NTS ); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { printf( "Successfully connected\n" ); } SQLDisconnect( dbc ); } SQLFreeHandle( SQL_HANDLE_DBC, dbc ); } SQLFreeHandle( SQL_HANDLE_ENV, env ); return 0;}

289

Page 304: Adaptive Server Anywhere

连接到数据源

连接到数据源连接到数据源连接到数据源连接到数据源

本节说明如何使用 ODBC 函数建立一个到 Adaptive Server Anywhere 数据库的连接。

选择选择选择选择 ODBC 连接函数连接函数连接函数连接函数

ODBC 提供了一组连接函数,具体使用哪个函数取决于您需要的应用程

序部署方式和使用方式:

• SQLConnect 简单的连接函数。

SQLConnect 采用数据源名称,和可选的用户 ID 和口令。如果您

将数据源名称硬编码到应用程序中,可能希望使用 SQLConnect。

有关更多信息,请参阅 《Microsoft ODBC 程序员参考》中的

"SQLConnect"。

• SQLDriverConnect 使用连接字符串连接数据源。

SQLDriverConnect 允许应用程序使用数据源外部的特定于 Adaptive Server Anywhere 的连接信息。另外,您可以使用 SQLDriverConnect 来请求 Adaptive Server Anywhere 驱动程序提示

用户提供连接信息。

SQLDriverConnect 还可用来在不指定数据源的情况下进行连接。

有关更多信息,请参阅 《Microsoft ODBC 程序员参考》中的

"SQLDriverConnect"。

• SQLBrowseConnect 使用连接字符串 (例如 SQLDriverConnect)连接到数据源。

SQLBrowseConnect 允许您的应用程序创建自己的提示用户提供

连接信息的对话框,和用于浏览给特定驱动程序 (这里是 Adaptive Server Anywhere 驱动程序)使用的数据源的对话框。

有关更多信息,请参阅 《Microsoft ODBC 程序员参考》中的

"SQLBrowseConnect"。

290

Page 305: Adaptive Server Anywhere

第 7 章 ODBC 编程

本章中的示例主要使用 SQLDriverConnect。

有关可在连接字符串中使用的连接参数的完整列表,请参阅 "ASA 数据

库管理指南 > 连接参数和通信参数 > 连接参数 "。

建立连接建立连接建立连接建立连接

您的应用程序必须先建立连接,然后才能执行数据库操作。

❖ 建立建立建立建立 ODBC 连接:连接:连接:连接:

1 分配 ODBC 环境。

例如:

SQLHENVenv;SQLRETURN retcode;retcode = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );

2 声明 ODBC 版本。

通过声明该应用程序遵循 ODBC 版本 3, SQLSTATE 值和某些

其它版本相关的功能都将得到相应的设置。例如:

retcode = SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);

3 如果需要,可以汇编这些数据源或连接字符串。

根据您的应用程序的情况,您可以对数据源或连接字符串进行硬编码,也可以将它们存储在外部以获得更大的灵活性。

4 分配 ODBC 连接项。

例如:

retcode = SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );

5 设置任何必须在连接前设置的连接属性。

291

Page 306: Adaptive Server Anywhere

连接到数据源

有些连接属性必须在建立连接前进行设置,而其它的则既可以在之前设置也可以在之后设置。例如:

retcode = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );

有关更多信息,请参阅 "" 设置连接属性 " 第 292 页 "。

6 调用 ODBC 连接函数。

例如:

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {printf( "dbc allocated\n" );retcode = SQLConnect( dbc,

(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS, (SQLCHAR* ) "DBA", SQL_NTS, (SQLCHAR*) "SQL", SQL_NTS );

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){

// successfully connected.

您可以在 SQL Anywhere 目录中找到一个完整示例,即 Samples\ASA\ODBCConnect\odbcconnect.cpp。

注意注意注意注意 • SQL_NTS 每个传递到 ODBC 的字符串都有相应的长度。如果长

度是未知的,您可以传递 SQL_NTS,表示它是一个结尾标记为空

值字符 (\0) 的 " 以空值终止的字符串以空值终止的字符串以空值终止的字符串以空值终止的字符串 "。

• SQLSetConnectAttr 缺省情况下, ODBC 是以自动提交模式操

作的。通过将 SQL_AUTOCOMMIT 设置为 false 可关闭此模式。

有关更多信息,请参阅 "" 设置连接属性 " 第 292 页 "。

设置连接属性设置连接属性设置连接属性设置连接属性

SQLSetConnectAttr 函数用于控制关于连接的详细信息。例如,下列语

句会关闭 ODBC 自动提交行为。

retcode = SQLSetConnectAttr( dbc, SQL_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0 );

292

Page 307: Adaptive Server Anywhere

第 7 章 ODBC 编程

有关更多信息 (包括一个连接属性列表),请参阅 《Microsoft ODBC 程序员参考》中的 "SQLSetConnectAttr"。

通过连接参数可以控制连接的许多方面。有关信息,请参阅 "ASA 数据

库管理指南 > 连接到数据库 > 连接参数 "。

ODBC 应用程序中的线程和连接应用程序中的线程和连接应用程序中的线程和连接应用程序中的线程和连接

您可以开发用于 Adaptive Server Anywhere 的多线程 ODBC 应用程序。

建议您对每个线程使用不同的连接。

您可以对多个线程使用一个连接。但是,数据库服务器不允许一个连接同时有多个处于活动状态的请求。如果一个线程执行一个耗时较长的语句,所有其它线程就必须等待该请求完成。

293

Page 308: Adaptive Server Anywhere

执行 SQL 语句

执行执行执行执行 SQL 语句语句语句语句

ODBC 包括几个用于执行 SQL 语句的函数:

• 直接执行直接执行直接执行直接执行 Adaptive Server Anywhere 会对 SQL 语句进行语法分

析,拟定访问计划,然后执行语句。语法分析和访问计划的拟定称为 " 准备准备准备准备 " 语句。

• 准备好的执行准备好的执行准备好的执行准备好的执行 语句的准备与执行是分开进行的。对于重复执行

的语句来说,这样会避免重复准备,从而提高性能。

请参阅 "" 执行 prepared 语句 " 第 296 页 "。

直接执行语句直接执行语句直接执行语句直接执行语句

SQLExecDirect 函数准备并执行 SQL 语句。该语句也可以包含参数。

下面的代码段说明如何执行不带参数的语句。 SQLExecDirect 函数带有

一个语句句柄、一个 SQL 字符串和一个长度或终止指示符 (在这里是

一个以空值终止的字符串指示符)。

本节中描述的过程比较直接,但是灵活性不够。应用程序无法采用来自用户的任何输入来修改语句。有关更灵活的语句构造方法,请参阅 ""执行包含捆绑参数的语句 " 第 295 页 "。

❖ 在在在在 ODBC 应用程序中执行应用程序中执行应用程序中执行应用程序中执行 SQL 语句:语句:语句:语句:

1 使用 SQLAllocHandle 为语句分配句柄。

例如,下面的语句将类型为 SQL_HANDLE_STMT、名称为 stmt

的句柄分配在具有句柄 dbc 的连接上。

SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );

2 调用 SQLExecDirect 函数执行语句:

例如,下面几行代码声明并执行一个语句。 deletestmt 的声明

通常在函数开始部分进行:

294

Page 309: Adaptive Server Anywhere

第 7 章 ODBC 编程

SQLCHAR deletestmt[ STMT_LEN ] = "DELETE FROM department WHERE dept_id = 201";SQLExecDirect( stmt, deletestmt, SQL_NTS) ;

若想查看包含错误检查的完整示例,请参见"Samples\ASA\ODBCExecute\odbcexecute.cpp"。

有关 SQLExecDirect 的更多信息,请参阅 《Microsoft ODBC 程序员参

考》中的 "SQLExecDirect"。

执行包含捆绑参数的语句执行包含捆绑参数的语句执行包含捆绑参数的语句执行包含捆绑参数的语句

本节说明如何使用捆绑的参数为语句参数设置运行时的值,来构造和执行 SQL 语句。

❖ 在在在在 ODBC 应用程序中执行包含捆绑参数的应用程序中执行包含捆绑参数的应用程序中执行包含捆绑参数的应用程序中执行包含捆绑参数的 SQL 语句:语句:语句:语句:

1 使用 SQLAllocHandle 分配用于语句的句柄。

例如,下面的语句将类型为 SQL_HANDLE_STMT、名称为 stmt

的句柄分配在具有句柄 dbc 的连接上。

SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );

2 使用 SQLBindParameter 为语句捆绑参数。

例如,下面几行代码声明一些变量,这些变量持有部门 ID、部

门名称和管理人员 ID 以及语句字符串本身的值。然后这些代码

将参数捆绑到使用 stmt 语句句柄执行的语句的第一个、第二个

和第三个参数上。

#defined DEPT_NAME_LEN 20SQLINTEGER cbDeptID = 0, cbDeptName = SQL_NTS, cbManagerID = 0;SQLCHAR deptname[ DEPT_NAME_LEN ];SQLSMALLINT deptID, managerID;SQLCHAR insertstmt[ STMT_LEN ] = "INSERT INTO department " "( dept_id, dept_name, dept_head_id )" "VALUES (?, ?, ?,)";SQLBindParameter( stmt, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0,

295

Page 310: Adaptive Server Anywhere

执行 SQL 语句

&deptID, 0, &cbDeptID);SQLBindParameter( stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DEPT_NAME_LEN, 0, deptname, 0,&cbDeptName);SQLBindParameter( stmt, 3, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &managerID, 0, &cbManagerID);

3 为参数赋值。

例如,下面几行代码为第 2 步代码段的参数赋值。

deptID = 201; strcpy( (char * ) deptname, "Sales East" );managerID = 902;

通常,设置这些变量是为了响应用户操作。

4 使用 SQLExecDirect 执行语句。

例如,下面几行代码执行语句句柄 stmt 上的 insertstmt 中持有的

语句字符串。

SQLExecDirect( stmt, insertstmt, SQL_NTS) ;

此外,还可以为 prepared 语句 (意为 " 准备好的语句 ")使用捆绑参

数,从而为需要执行多次的语句带来更好的性能。有关更多信息,请参阅 "" 执行 prepared 语句 " 第 296 页 "。

上面的代码段不包含错误检查。若想查看包含错误检查的完整示例,请参见 "Samples\ASA\ODBCExecute\odbcexecute.cpp"。

有关 SQLExecDirect 的更多信息,请参阅 《Microsoft ODBC 程序员参

考》中的 "SQLExecDirect"。

执行执行执行执行 prepared 语句语句语句语句

prepared 语句可提高重复使用的语句的性能。 ODBC 为使用 prepared 语句提供了一整套函数。

有关 prepared 语句的介绍,请参阅 "" 准备语句 " 第 12 页 "。

296

Page 311: Adaptive Server Anywhere

第 7 章 ODBC 编程

❖ 执行准备好的执行准备好的执行准备好的执行准备好的 SQL 语句:语句:语句:语句:

1 使用 SQLPrepare 准备语句。

例如,下面的代码段说明如何准备 INSERT 语句:

SQLRETURN retcode;SQLHSTMT stmt;retcode = SQLPrepare( stmt, "INSERT INTO department ( dept_id, dept_name, dept_head_id ) VALUES (?, ?, ?,)", SQL_NTS);

在此示例中:

• retcode 包含返回代码,应测试这些代码来检查操作是成

功还是失败。

• stmt 提供语句句柄,供以后引用。

• ? 问号是表示语句参数的占位符。

2 使用 SQLBindParameter 设置语句参数值。

例如,下面的函数调用设置 dept_id 变量的值:

SQLBindParameter( stmt, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &sDeptID, 0, &cbDeptID);

在此示例中:

• stmt 是语句句柄

• 1 指示此调用设置第一个占位符的值。

• SQL_PARAM_INPUT 指示该参数是输入语句。

297

Page 312: Adaptive Server Anywhere

执行 SQL 语句

• SQL_C_SHORT 指示该应用程序中正在使用的 C 数据

类型。

• SQL_INTEGER 指示数据库中正在使用的 SQL 数据类

型。

• 下面的两个参数指示列的精度,以及小数位数:对于整

数,两参数均为零。

• &sDeptID 是指向参数值缓冲区的指针。

• 0 指示缓冲区的长度,以字节计。

• &cbDeptID 是指向参数值长度缓冲区的指针。

3 捆绑其它两个参数并给 sDeptId 赋值。

4 执行该语句:

retcode = SQLExecute( stmt);

第 2 至 4 步可重复多次。

5 删除该语句。

删除语句将释放与该语句相关联的资源。使用 SQLFreeHandle 可以删除语句。

若想查看包含错误检查的完整示例,请参见"Samples\ASA\ODBCPrepare\odbcprepare.cpp"。

有关 SQLPrepare 的更多信息,请参阅 《Microsoft ODBC 程序员参

考》中的 "SQLPrepare"。

298

Page 313: Adaptive Server Anywhere

第 7 章 ODBC 编程

使用结果集使用结果集使用结果集使用结果集

ODBC 应用程序使用游标来操纵和更新结果集。 Adaptive Server Anywhere 为各种游标和游标操作提供广泛的支持。

有关游标的介绍,请参阅 "" 使用游标 " 第 20 页 "。

选择游标特性选择游标特性选择游标特性选择游标特性

执行语句和操纵结果集的 ODBC 函数使用游标执行它们的任务。应用

程序每次执行 SQLExecute 或 SQLExecDirect 函数时,都会隐式打开游

标。

如果游标在结果集中只以前进方向移动而不更新结果集,对于这种应用情况,游标行为相对比较直接。缺省情况下, ODBC 应用程序会请求

此行为。 ODBC 定义一个只读、只进游标, Adaptive Server Anywhere 针对这种情况提供了已优化性能的游标。

有关只进游标的简单示例,请参阅 "" 检索数据 " 第 300 页 "。

如果游标需要在结果集中向前和向后双向滚动 (例如在很多图形用户界面应用程序中),这种应用情况下的游标行为较为复杂。当应用程序返回到一个由某种别的应用程序更新的行时,它会怎样? ODBC 定义

了多种 " 可滚动游标可滚动游标可滚动游标可滚动游标 ",从而使您可以内置适合您的应用程序的行为。

Adaptive Server Anywhere 提供了一整套游标,可以满足各种 ODBC 可滚动游标类型的要求。

通过调用定义语句属性的 SQLSetStmtAttr 函数,您可以设置所需的 ODBC 游标特性。执行创建结果集的语句之前您必须调用 SQLSetStmtAttr。

您可以使用 SQLSetStmtAttr 来设置很多游标特性。决定 Adaptive Server Anywhere 提供的游标类型的特性包括以下几种:

• SQL_ATTR_CURSOR_SCROLLABLE 对于可滚动游标,设置

为, SQL_SCROLLABLE ;对于只进游标,设置为 SQL_NONSCROLLABLE。 SQL_NONSCROLLABLE 是缺省设

置。

• SQL_ATTR_CONCURRENCY 设置为下列值之一:

299

Page 314: Adaptive Server Anywhere

使用结果集

• SQL_CONCUR_READ_ONLY 不允许更新。

SQL_CONCUR_READ_ONLY 是缺省设置。

• SQL_CONCUR_LOCK 使用足以确保该行能够得到更新的

低锁定级别。

• SQL_CONCUR_ROWVER 使用优化的并发控制,比较数

据行的版本 (例如, SQLBase ROWID 或 Sybase TIMESTAMP)。

• SQL_CONCUR_VALUES 使用优化的并发控制,比较值。

有关更多信息,请参阅 《Microsoft ODBC 程序员参考》中的

"SQLSetStmtAttr"。

示例示例示例示例 下面的代码段请求一个只读的、可滚动游标:

SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );SQLSetStmtAttr( stmt, SQL_ATTR_CURSOR_SCROLLABLE,

SQL_SCROLLABLE, 0 );

检索数据检索数据检索数据检索数据

若要从数据库检索行,可使用 SQLExecute 或 SQLExecDirect 执行 SELECT 语句。这将为该语句打开一个游标。然后使用 SQLFetch 或 SQLExtendedFetch 通过游标读取行。当应用程序使用 SQLFreeHandle 释放语句后,它将关闭游标。

若要从游标读取值,您的应用程序可以使用 SQLBindCol 或 SQLGetData。如果使用 SQLBindCol,则会在每次读取时自动检索值。

如果使用 SQLGetData,您必须在每次读取后为每一列调用它。

SQLGetData 用来逐段读取 LONG VARCHAR 或 LONG BINARY 之类的

列的值。另一种方法,还可以将 SQL_MAX_LENGTH 语句属性设置为

一个很大的值,使之能够包含列的整个值。SQL_ATTR_MAX_LENGTH 的缺省值为 256 kb。

下面的代码段在查询时打开游标,并通过游标检索数据。其中未包含错误检查,这样该示例读起来更容易。该代码段节选自一个完整示例,该完整示例位于 Samples\ASA\ODBCSelect\odbcselect.cpp。

300

Page 315: Adaptive Server Anywhere

第 7 章 ODBC 编程

SQLINTEGER cbDeptID = 0, cbDeptName = SQL_NTS, cbManagerID = 0;SQLCHAR deptname[ DEPT_NAME_LEN ];SQLSMALLINT deptID, managerID;SQLHENV env;SQLHDBC dbc;SQLHSTMT stmt;SQLRETURN retcode;SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env );SQLSetEnvAttr( env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); SQLAllocHandle( SQL_HANDLE_DBC, env, &dbc );SQLConnect( dbc,

(SQLCHAR*) "ASA 8.0 Sample", SQL_NTS,(SQLCHAR*) "DBA", SQL_NTS,(SQLCHAR*) "SQL", SQL_NTS );

SQLAllocHandle( SQL_HANDLE_STMT, dbc, &stmt );SQLBindCol( stmt, 1, SQL_C_SSHORT, &deptID, 0, &cbDeptID);SQLBindCol( stmt, 2, SQL_C_CHAR, deptname, sizeof(deptname), &cbDeptName);SQLBindCol( stmt, 3, SQL_C_SSHORT, &managerID, 0, &cbManagerID);SQLExecDirect( stmt, (SQLCHAR * ) "SELECT dept_id, dept_name, dept_head_id FROM DEPARTMENT "

"ORDER BY dept_id", SQL_NTS ); while( ( retcode = SQLFetch( stmt ) ) != SQL_NO_DATA ){

printf( "%d %20s %d\n", deptID, deptname, managerID );}SQLFreeHandle( SQL_HANDLE_STMT, stmt );SQLDisconnect( dbc );SQLFreeHandle( SQL_HANDLE_DBC, dbc );SQLFreeHandle( SQL_HANDLE_ENV, env );

游标中可读取的行位置数受整数的大小制约。您可以读取的行数 大为 2147483646,该数字比一个整数中能够包含的 大值小一。使用负数

(从后向前编行号)时,可以读取到的行数比一个整数所能包含的 大负值大一。

301

Page 316: Adaptive Server Anywhere

使用结果集

通过游标更新和删除行通过游标更新和删除行通过游标更新和删除行通过游标更新和删除行

《Microsoft ODBC 程序员参考》建议您使用 SELECT…FOR UPDATE 来指示可以使用定位的操作更新查询。您不需要在 Adaptive Server Anywhere 中使用 FOR UPDATE 子句:只要符合下列条件, SELECT 语句就可以更新:

• 基础的查询支持更新。

就是说,只要结果中各列内的数据修改语句有意义,定位的数据修改语句就可在游标上执行。

ANSI_UPDATE_CONSTRAINTS 数据库选项将查询的类型限制为

可更新的类型。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库选项 > ANSI_UPDATE_CONSTRAINTS 选项 [compatibility]"。

• 游标类型支持更新。

如果您使用的是只读游标,则不能更新结果集。

ODBC 提供两种方法来执行定位的更新和删除:

• 使用 SQLSetPos 函数。

根据提供的参数 (SQL_POSITION、 SQL_REFRESH、

SQL_UPDATE、 SQL_DELETE), SQLSetPos 设置游标位置,让

应用程序刷新、更新或删除结果集中的数据。

这是 Adaptive Server Anywhere 中使用的方法。

• 使用 SQLExecute 发送定位的 UPDATE 和 DELETE 语句。这种方

法不能用在 Adaptive Server Anywhere 中。

302

Page 317: Adaptive Server Anywhere

第 7 章 ODBC 编程

使用书签使用书签使用书签使用书签

ODBC 提供 " 书签书签书签书签 ",书签是游标中用来标识行的值。除动态游标外,

Adaptive Server Anywhere 支持其它各种游标的书签。

ODBC 3.0 之前,数据库只能指定是否支持书签:没有用于为每种游标

类型提供这些信息的界面。数据库服务器没有办法指示支持的游标书签类型。对于 ODBC 2 应用程序, Adaptive Server Anywhere 会返回信息

说明它的确支持书签。这样,虽然您尝试将书签用于动态游标时不会遇到什么阻碍,但是,您不应当这样组合使用。

303

Page 318: Adaptive Server Anywhere

调用存储过程

调用存储过程调用存储过程调用存储过程调用存储过程

本节说明如何创建和调用存储过程以及如何处理来自 ODBC 应用程序

的结果。

有关存储过程和触发器的完整说明,请参阅 "ASA SQL 用户指南 > 使用

过程、触发器和批处理 "。

过程和结果集过程和结果集过程和结果集过程和结果集 有两种类型的过程:返回结果集的过程和不返回结果集的过程。您可以使用 SQLNumResultCols 来区分:如果过程不返回结果,则结果列数为

零。如果有结果集,则您可以使用 SQLFetch 或 SQLExtendedFetch 读取值,就像任何其它游标一样。

过程的参数应当使用参数标记 (问号)来传递。使用 SQLBindParameter 可为每个参数标记指派存储区域,无论是 INPUT、OUTPUT 还是 INOUT 参数都可以。

要处理多个结果集, ODBC 必须描述当前正在执行的游标,而不是描

述由过程定义的结果集。因此, ODBC 并不总是按照存储过程定义中

的 RESULT 子句中的定义来描述列名称。要避免出现此问题,您可以在

过程结果集游标中使用列别名。

示例示例示例示例 此示例创建和调用不返回结果集的过程。该过程采用一个 INOUT 参数,并会增加它的值。在此示例中,变量 num_col 的值将为零,这是因

为该过程不返回结果集。为了使示例更容易读,这里省略了错误检查。

HDBC dbc;HSTMT stmt;long i;SWORD num_col;/* Create a procedure */SQLAllocStmt( dbc, &stmt );SQLExecDirect( stmt,

"CREATE PROCEDURE Increment( INOUT a INT )" \" BEGIN" \

" SET a = a + 1" \" END", SQL_NTS );

/* Call the procedure to increment 'i' */i = 1;SQLBindParameter( stmt, 1, SQL_C_LONG, SQL_INTEGER, 0,

304

Page 319: Adaptive Server Anywhere

第 7 章 ODBC 编程

0, &i, NULL );SQLExecDirect( stmt, "CALL Increment( ? )",

SQL_NTS );SQLNumResultCols( stmt, &num_col );do_something( i );

示例示例示例示例 此示例调用一个过程,该过程返回一个结果集。在此示例中,变量 num_col 的值为 2,因为该过程返回的结果集具有两列。同样,错误检

查已被省略,这样该示例更容易读。

HDBC dbc;HSTMT stmt;SWORD num_col;RETCODE retcode;char emp_id[ 10 ];char emp_lame[ 20 ];/* Create the procedure */SQLExecDirect( stmt,

"CREATE PROCEDURE employees()" \" RESULT( emp_id CHAR(10), emp_lname CHAR(20))"\" BEGIN" \" SELECT emp_id, emp_lame FROM employee" \" END", SQL_NTS );

/* Call the procedure - print the results */SQLExecDirect( stmt, "CALL employees()", SQL_NTS );SQLNumResultCols( stmt, &num_col );SQLBindCol( stmt, 1, SQL_C_CHAR, &emp_id,

sizeof(emp_id), NULL );SQLBindCol( stmt, 2, SQL_C_CHAR, &emp_lname,

sizeof(emp_lname), NULL );for( ;; ) {

retcode = SQLFetch( stmt );if( retcode == SQL_NO_DATA_FOUND ) {

retcode = SQLMoreResults( stmt );if( retcode == SQL_NO_DATA_FOUND ) break;

} else {do_something( emp_id, emp_lname );

}}

305

Page 320: Adaptive Server Anywhere

处理错误

处理错误处理错误处理错误处理错误

ODBC 中的错误是使用来自每个 ODBC 函数调用和 SQLError 函数或 SQLGetDiagRec 函数的返回值进行报告的。 SQLError 函数用于 ODBC 版本, 高到 3.0 版 (不包括 3.0 版)。自 3.0 版 起 SQLError 函数被废

弃,改为了 SQLGetDiagRec 函数。

每个 ODBC 函数都返回一个 SQLRETURN,其值为下列状态代码为之

一:

每个环境、连接和语句句柄都可能有与之相关联的一个或多个错误或警告。每个对 SQLError 或 SQLGetDiagRec 的调用都返回关于一个错误的

信息,然后删除关于该错误的信息。如果您不调用 SQLError 或 SQLGetDiagRec 删除所有错误,则将在执行下一个将同一句柄作为参

数来传递的函数调用时删除这些错误。

状态代码状态代码状态代码状态代码 说明说明说明说明

SQL_SUCCESS 无错误。

SQL_SUCCESS_WITH_INFO

该函数完成,但是每一个对 SQLError 的调

用都将显示一个警告。这种状态 常见的情况是:返回的值太长,应用程序提供的缓冲区不够用。

SQL_ERROR 函数未完成,因为出现了错误。调用 SQLError 可获得关于此问题的更多信息。

SQL_INVALID_HANDLE 作为参数传递的环境、连接或语句句柄无效。如果在释放句柄后再使用该句柄,或者句柄为空值指针,则通常会发生这种情况。

SQL_NO_DATA_FOUND 没有可用信息。使用这种状态的 常见情况是在从游标进行读取时,这种状态表示游标中没有更多行。

SQL_NEED_DATA 参数需要数据。这是一项高级特性, ODBC SDK 文档中的 SQLParamData 和 SQLPutData 下面对其

作了说明。

306

Page 321: Adaptive Server Anywhere

第 7 章 ODBC 编程

每个对 SQLError 的调用都会传递三个句柄,分别用于环境、连接和语

句。第一个调用使用 SQL_NULL_HSTMT 获取与连接相关联的错误。

类似地,使用 SQL_NULL_DBC 和 SQL_NULL_HSTMT 的调用将获取

任何与环境句柄相关联的错误。

每个对 SQLGetDiagRec 的调用将传递环境、连接或语句句柄。第一个

调用传递句柄类型 SQL_HANDLE_DBC 以获取与连接关联的错误。第

二个调用传递句柄类型 SQL_HANDLE_STMT 以获取与刚执行的语句关

联的错误。

如果有错误要报告, SQLError 和 SQLGetDiagRec 就会返回 SQL_SUCCESS (不是 SQL_ERROR),如果没有其它错误要报告,就

返回 SQL_NO_DATA_FOUND。

示例示例示例示例 1 下面的代码段使用了 SQLError 和返回代码:

/* Declare required variables */SQLHDBC dbc;SQLHSTMT stmt;SQLRETURN retcode;UCHAR errmsg[100];/* code omitted here */retcode = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt );if( retcode == SQL_ERROR ){ SQLError( env, dbc, SQL_NULL_HSTMT, NULL, NULL, errmsg, sizeof(errmsg), NULL ); /* Assume that print_error is defined */ print_error( "Allocation failed", errmsg ); return;}/* Delete items for order 2015 */retcode = SQLExecDirect( stmt, "delete from sales_order_items where id=2015", SQL_NTS );if( retcode == SQL_ERROR ) { SQLError( env, dbc, stmt, NULL, NULL, errmsg, sizeof(errmsg), NULL ); /* Assume that print_error is defined */ print_error( "Failed to delete items", errmsg ); return;}

示例示例示例示例 2 下面的代码段使用了 SQLGetDiagRec 并返回代码:

307

Page 322: Adaptive Server Anywhere

处理错误

/* Declare required variables */SQLHDBC dbc;SQLHSTMT stmt;SQLRETURN retcode;SQLSMALLINT errmsglen;SQLINTEGER errnative;UCHAR errmsg[255];UCHAR errstate[5];/* code omitted here */retcode = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt );if( retcode == SQL_ERROR ){ SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, errstate,

&errnative, errmsg, sizeof(errmsg), &errmsglen); /* Assume that print_error is defined */ print_error( "Allocation failed", errstate,

errnative, errmsg ); return;

}/* Delete items for order 2015 */retcode = SQLExecDirect( stmt,

"delete from sales_order_items where id=2015", SQL_NTS );

if( retcode == SQL_ERROR ) { SQLGetDiagRec(SQL_HANDLE_STMT, stmt, recnum,

errstate, &errnative, errmsg, sizeof(errmsg), &errmsglen);

/* Assume that print_error is defined */ print_error("Failed to delete items", errstate,

errnative, errmsg ); return;

}

308

Page 323: Adaptive Server Anywhere

第 8 章

数据库工具接口数据库工具接口数据库工具接口数据库工具接口

关于本章关于本章关于本章关于本章 本章介绍了如何使用随 Adaptive Server Anywhere 提供的数据库工具库

来将数据库管理功能添加到 C 或 C++ 应用程序中。

309

Page 324: Adaptive Server Anywhere

数据库工具接口简介

数据库工具接口简介数据库工具接口简介数据库工具接口简介数据库工具接口简介

Sybase Adaptive Server Anywhere 包括用于管理数据库的 Sybase Central 和一组实用程序。这些数据库管理实用程序执行各种任务,如备份数据库、创建数据库、将事务日志转换为 SQL 等。

支持的平台支持的平台支持的平台支持的平台 所有的数据库管理实用程序都使用一个名为数据库工具库的共享库。为每个 Windows 操作系统都提供了共享库,该库的名称为 dbtool8.dll。

您可以开发自己的数据库管理实用程序,也可以通过调用数据库工具库来将数据库管理功能合并到您的应用程序中。本章介绍数据库工具库的接口。在本章中,我们假定您熟悉如何从所使用的开发环境中调用 DLL。

数据库工具库为每个数据库管理实用程序都提供了函数或入口点。另外,函数的调用必须是在使用其它数据库工具函数之前和完成其它数据库工具函数的使用之后。

Windows CE dbtool8.dll 库也提供给 Windows CE,但是其中只包括 DBToolsInit、DBToolsFini、 DBRemoteSQL 和 DBSynchronizeLog 的入口点。并且没

有为 Windows CE 提供其它工具。

dbtools.h 头文件头文件头文件头文件 Adaptive Server Anywhere 包括的 dbtools 头文件列出 DBTools 库的入口

点以及用于将信息传入和传出该库的结构。 dbtools.h 文件安装到您

的安装目录下的 h 子目录中。您应当查阅 dbtools.h 文件以获得有关

入口点和结构成员的 新信息。

dbtools.h 头文件还包括两个文件:

• sqlca.h 这是为解析各种宏 (而非 SQLCA 本身)而提供的。

• dllapi.h 为与操作系统和语言相关的宏定义预处理器宏。

sqldef.h 头文件还包括错误返回值。

310

Page 325: Adaptive Server Anywhere

第 8 章 数据库工具接口

使用数据库工具接口使用数据库工具接口使用数据库工具接口使用数据库工具接口

本节概述如何开发通过使用 DBTools 接口来管理数据库的应用程序。

使用导入库使用导入库使用导入库使用导入库

为了使用 DBTools 函数,您必须针对包含所需的函数定义的 DBTools"导入库导入库导入库导入库 " 链接您的应用程序。

支持的平台支持的平台支持的平台支持的平台 导入库是编译器特定的库,提供给除 Windows CE 以外的 Windows 操作

系统。 DBTools 接口的导入库是随 Adaptive Server Anywhere 提供的,

可在您的安装目录下每个操作系统目录的 lib 子目录下找到。所提供的 DBTools 导入库如下所示:

启动和完成启动和完成启动和完成启动和完成 DBTools 库库库库

在使用任何 DBTools 函数之前,您必须调用 DBToolsInit。当使用完 DBTools DLL 时,您必须调用 DBToolsFini。

DBToolsInit 和 DBToolsFini 函数的主要用途是允许 DBTools DLL 装载 Adaptive Server Anywhere 语言 DLL。语言 DLL 包含了 DBTools 内部使

用的所有本地化版本的错误消息和提示。如果 DBToolsFini 未被调用,

语言 DLL 的引用计数将不会减少,而且不会被卸载,因此请注意:一

定要有一对匹配的 DBToolsInit/DBToolsFini 调用。

下列代码段阐释了如何初始化和清除 DBTools:

编译器编译器编译器编译器 库库库库

Watcom win32\dbtlstw.lib

Microsoft win32\dbtlstM.lib

Borland win32\dbtlstB.lib

311

Page 326: Adaptive Server Anywhere

使用数据库工具接口

// Declarationsa_dbtools_infoinfo;short ret;//Initialize the a_dbtools_info structurememset( &info, 0, sizeof( a_dbtools_info) );info.errorrtn = (MSG_CALLBACK)MyErrorRtn;// initialize DBToolsret = DBToolsInit( &info );if( ret != EXIT_OKAY ) {

// DLL initialization failed...

}// call some DBTools routines . . ....// cleanup the DBTools dllDBToolsFini( &info );

调用调用调用调用 DBTools 函数函数函数函数

所有工具都是通过先填写结构然后在 DBTools DLL 中调用函数 (或 "入口点入口点入口点入口点 ")来运行的。每个入口点都将指向单个结构的指针视为参数。

下面的示例展示了如何在 Windows 操作系统上使用 DBBackup 函数。

// Initialize the structurea_backup_db backup_info;memset( &backup_info, 0, sizeof( backup_info ) );// Fill out the structurebackup_info.version = DB_TOOLS_VERSION_NUMBER;backup_info.output_dir = "C:\BACKUP";backup_info.connectparms ="uid=DBA;pwd=SQL;dbf=asademo.db";backup_info.startline = "dbeng8.EXE";backup_info.confirmrtn = (MSG_CALLBACK) ConfirmRtn ;backup_info.errorrtn = (MSG_CALLBACK) ErrorRtn ;backup_info.msgrtn = (MSG_CALLBACK) MessageRtn ;backup_info.statusrtn = (MSG_CALLBACK) StatusRtn ;backup_info.backup_database = TRUE;// start the backupDBBackup( &backup_info );

有关 DBTools 结构成员的信息,请参阅 "DBTools 结构 " 第 334 页。

312

Page 327: Adaptive Server Anywhere

第 8 章 数据库工具接口

软件组件的返回代码软件组件的返回代码软件组件的返回代码软件组件的返回代码

所有的数据库工具都是作为 DLL 中的入口点提供的。这些入口点使用

下列返回代码:

使用回调函数使用回调函数使用回调函数使用回调函数

DBTools 结构中有几个类型为 MSG_CALLBACK 的元素,这些是指向

回调函数的指针。

使用回调函数使用回调函数使用回调函数使用回调函数 回调函数允许 DBTools 函数将对操作的控制返回到用户的调用应用程序

中。 DBTools 库使用回调函数来处理因以下四种用途而由 DBTools 函数

发送到用户的消息:

代码代码代码代码 解释解释解释解释

0 成功

1 常规失败

2 文件格式无效

3 文件未找到,无法打开

4 内存不足

5 被用户终止

6 通信失败

7 缺少一个必需的数据库名

8 客户 / 服务器协议不匹配

9 无法连接到数据库服务器

10 数据库服务器未运行

11 数据库服务器未找到

254 已到达停止时间

255 命令行上的参数无效

313

Page 328: Adaptive Server Anywhere

使用数据库工具接口

• 确认确认确认确认 当需要由用户确认操作时调用。例如,如果备份目录不存

在,则工具 DLL 询问是否需要创建它。

• 错误消息错误消息错误消息错误消息 在发生错误 (如在执行某个操作时磁盘空间不足)时

被调用以处理消息。

• 信息消息信息消息信息消息信息消息 针对工具调用以便向用户显示某些消息 (如正进行备

份的当前表的名称)。

• 状态信息状态信息状态信息状态信息 针对工具调用以显示操作的状态 (如卸载表时的完成

百分比)。

将回调函数指派给结将回调函数指派给结将回调函数指派给结将回调函数指派给结构构构构

您可以将回调例程直接指派给结构。下面的语句是使用备份结构的示例:

backup_info.errorrtn = (MSG_CALLBACK) MyFunction

MSG_CALLBACK 是在随 Adaptive Server Anywhere 提供的 dllapi.h 头文件中定义的。工具例程可以用应当出现在相应的用户界面中的消息回调 " 调用 " 应用程序,而无论该用户界面是窗口环境、基于字符的系

统上的标准输出还是其它用户界面。

确认回调函数的示例确认回调函数的示例确认回调函数的示例确认回调函数的示例 下面这个示例确认例程要求用户对提示回答 " 是 " 或 " 否 " 并返回用户

的选择:

extern short _callback ConfirmRtn(char far * question )

{int ret;if( question != NULL ) {

ret = MessageBox( HwndParent, question,"Confirm", MB_ICONEXCLAMTION|MB_YESNO );

}return( 0 );

}

错误回调函数的示例错误回调函数的示例错误回调函数的示例错误回调函数的示例 下面的示例显示错误消息处理例程,它在一个消息框中显示错误消息。

314

Page 329: Adaptive Server Anywhere

第 8 章 数据库工具接口

extern short _callback ErrorRtn(char far * errorstr )

{if( errorstr != NULL ) {

ret = MessageBox( HwndParent, errorstr,"Backup Error", MB_ICONSTOP|MB_OK );

}return( 0 );

}

消息回调函数的示例消息回调函数的示例消息回调函数的示例消息回调函数的示例 消息回调函数的公用执行会将消息输出到屏幕上:

extern short _callback MessageRtn(char far * errorstr )

{if( messagestr != NULL ) {OutputMessageToWindow( messagestr );}return( 0 );

}

状态回调函数的示例状态回调函数的示例状态回调函数的示例状态回调函数的示例 状态回调例程在工具需要显示操作的状态 (如卸载表时的完成百分比)时被调用。公用执行代码会再次只将消息输出到屏幕上:

extern short _callback StatusRtn(char far * statusstr )

{if( statusstr == NULL ) {

return FALSE;}OutputMessageToWindow( statustr );return TRUE;

}

版本号和兼容性版本号和兼容性版本号和兼容性版本号和兼容性

每个结构都有一个指示版本号的成员。您应当使用该版本成员来保存应用程序开发所针对的 DBTools 库的版本。 DBTools 库的当前版本号作为

常量包括在 dbtools.h 头文件中。

315

Page 330: Adaptive Server Anywhere

使用数据库工具接口

❖ 将当前版本号指派给结构:将当前版本号指派给结构:将当前版本号指派给结构:将当前版本号指派给结构:

• 在调用 DBTools 函数之前,将版本常量指派给结构的版本成

员。下行将当前的版本指派给备份结构:

backup_info.version = DB_TOOLS_VERSION_NUMBER;

兼容性兼容性兼容性兼容性 版本号允许应用程序继续针对较新版本的 DBTools 库工作。即使新成员

已添加到 DBTools 结构中, DBTools 函数也使用由应用程序提供的版本

号来允许应用程序工作。

应用程序将不针对较旧版本的 DBTools 库工作。

使用位字段使用位字段使用位字段使用位字段

许多 DBTools 结构都使用位字段来以紧凑的方式保存布尔信息。例如,

备份结构具有下列位字段:

a_bit_fieldbackup_database: 1;a_bit_fieldbackup_logfile: 1;a_bit_fieldbackup_writefile: 1;a_bit_fieldno_confirm: 1;a_bit_fieldquiet: 1;a_bit_fieldrename_log: 1;a_bit_fieldtruncate_log : 1;a_bit_fieldrename_local_log: 1;

每个位字段的长度都是一位,这由结构声明中冒号右侧的 1 来指示。所

使用的特定数据类型取决于指派给 a_bit_field 的值, a_bit_field 在 dbtools.h 的顶端设置且与操作系统相关。

将整数值 0 或 1 指派给位字段以便将布尔信息传递给该结构。

DBTools 的示例的示例的示例的示例

您可以在 SQL Anywhere 目录的 Samples\ASA\DBTools 子目录中查找

该示例以及它的编译指导。示例程序本身是 Samples\ASA\DBTools\main.c。该示例阐释了如何使用 DBTools 库执

行数据库备份。

316

Page 331: Adaptive Server Anywhere

第 8 章 数据库工具接口

# define WINNT#include <stdio.h>#include "windows.h"#include "string.h"#include "dbtools.h"extern short _callback ConfirmCallBack(char far * str){

if( MessageBox( NULL, str, "Backup", MB_YESNO|MB_ICONQUESTION ) == IDYES ) {return 1;

}return 0;

}extern short _callback MessageCallBack( char far * str){

if( str != NULL ) {fprintf( stdout, "%s", str );fprintf( stdout, "\n" );fflush( stdout );

}return 0;

}extern short _callback StatusCallBack( char far * str ){

if( str != NULL ) {fprintf( stdout, "%s", str );fprintf( stdout, "\n" );fflush( stdout );

}return 0;

}extern short _callback ErrorCallBack( char far * str ){

if( str != NULL ) {fprintf( stdout, "%s", str );fprintf( stdout, "\n" );fflush( stdout );

}return 0;

}// Main entry point into the program.int main( int argc, char * argv[] ){

a_backup_db backup_info;a_dbtools_info dbtinfo;char dir_name[ _MAX_PATH + 1];char connect[ 256 ];HINSTANCE hinst;FARPROC dbbackup;

317

Page 332: Adaptive Server Anywhere

使用数据库工具接口

FARPROC dbtoolsinit;FARPROC dbtoolsfini;// Always initialize to 0 so new versions//of the structure will be compatible.memset( &backup_info, 0, sizeof( a_backup_db ) );backup_info.version = DB_TOOLS_VERSION_8_0_00;backup_info.quiet = 0;backup_info.no_confirm = 0;backup_info.confirmrtn =

(MSG_CALLBACK)ConfirmCallBack;backup_info.errorrtn = (MSG_CALLBACK)ErrorCallBack;backup_info.msgrtn = (MSG_CALLBACK)MessageCallBack;backup_info.statusrtn =

(MSG_CALLBACK)StatusCallBack;if( argc > 1 ) {

strncpy( dir_name, argv[1], _MAX_PATH );} else {

// DBTools does not expect (or like) the// trailing slashstrcpy( dir_name, "c:\\temp" );

}backup_info.output_dir = dir_name;if( argc > 2 ) {

strncpy( connect, argv[2], 255 );} else {

// Assume that the engine is already running.strcpy( connect, "DSN=ASA 8.0 Sample" );

}backup_info.connectparms = connect;backup_info.startline = ";backup_info.quiet = 0;backup_info.no_confirm = 0;backup_info.backup_database = 1;backup_info.backup_logfile = 1;backup_info.backup_writefile = 1;backup_info.rename_log = 0;backup_info.truncate_log = 0;hinst = LoadLibrary( "dbtool8.dll" );if( hinst == NULL ) {

// Failedreturn 0;

}dbtinfo.errorrtn = (MSG_CALLBACK)ErrorCallBack;dbbackup = GetProcAddress( (HMODULE)hinst,

"_DBBackup@4" );dbtoolsinit = GetProcAddress( (HMODULE)hinst,

318

Page 333: Adaptive Server Anywhere

第 8 章 数据库工具接口

"_DBToolsInit@4" );dbtoolsfini = GetProcAddress( (HMODULE)hinst,

"_DBToolsFini@4" );(*dbtoolsinit)( &dbtinfo );(*dbbackup)( &backup_info );(*dbtoolsfini)( &dbtinfo );FreeLibrary( hinst );return 0;

}

319

Page 334: Adaptive Server Anywhere

DBTools 函数

DBTools 函数函数函数函数

本节介绍了 DBTools 库中可用的函数。这些函数按字母顺序列出。

DBBackup 函数函数函数函数

函数函数函数函数 数据库备份函数。该函数由 dbbackup 命令行实用程序使用。

原型原型原型原型 short DBBackup ( const a_backup_db * backup-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 DBBackup 函数管理所有的数据库备份任务。

有关这些任务的说明,请参阅 "ASA 数据库管理指南 > 数据库管理实用

程序 > Backup 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_backup_db 结构 " 第 334 页

DBChangeLogName 函数函数函数函数

函数函数函数函数 更改事务日志文件的名称。该函数由 dblog 命令行实用程序使用。

原型原型原型原型 short DBChangeLogName ( const a_change_log * change-log );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

参数参数参数参数 说明说明说明说明

backup-db 指向 "a_backup_db 结构 " 第 334 页 的指针

参数参数参数参数 说明说明说明说明

change-log 指向 "a_change_log 结构 " 第 336 页 的指针

320

Page 335: Adaptive Server Anywhere

第 8 章 数据库工具接口

用法用法用法用法 dblog 命令行实用程序的 -t 选项更改事务日志的名称。

DBChangeLogName 向该函数提供编程接口。

有关 dblog 实用程序的说明,请参阅 "ASA 数据库管理指南 > 数据库管

理实用程序 > Transaction Log 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_change_log 结构 " 第 336 页

DBChangeWriteFile 函数函数函数函数

函数函数函数函数 将写文件更改为引用另一个数据库文件。该函数由应用了 -d 选项的 dbwrite 命令行实用程序使用。

原型原型原型原型 short DBChangeWriteFile ( const a_writefile * writefile );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Write File 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Write File 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "DBCreateWriteFile 函数 " 第 323 页

"DBStatusWriteFile 函数 " 第 328 页

"a_writefile 结构 " 第 364 页

DBCollate 函数函数函数函数

函数函数函数函数 从数据库中抽取归类序列。

原型原型原型原型 short DBCollate ( const a_db_collation * db-collation );

参数参数参数参数 说明说明说明说明

writefile 指向 "a_writefile 结构 " 第 364 页 的指针

321

Page 336: Adaptive Server Anywhere

DBTools 函数

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Collation 实用程序及其功能的信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > Collation 实用程序 "

另请参阅另请参阅另请参阅另请参阅 "a_db_collation 结构 " 第 343 页

DBCompress 函数函数函数函数

函数函数函数函数 压缩数据库文件。该函数由 dbshrink 命令行实用程序使用。

原型原型原型原型 short DBCompress ( const a_compress_db * compress-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Compression 实用程序及其功能的信息,请参阅 "ASA 数据库管理

指南 > 数据库管理实用程序 > Compression 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_compress_db 结构 " 第 338 页

DBCreate 函数函数函数函数

函数函数函数函数 创建数据库。该函数由 dbinit 命令行实用程序使用。

原型原型原型原型 short DBCreate ( const a_create_db * create-db );

参数参数参数参数 说明说明说明说明

db-collation 指向 "a_db_collation 结构 " 第 343 页 的指针

参数参数参数参数 说明说明说明说明

compress-db 指向 "a_compress_db 结构 " 第 338 页 的指针

322

Page 337: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Initialization 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > Initialization 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_create_db 结构 " 第 340 页

DBCreateWriteFile 函数函数函数函数

函数函数函数函数 创建写文件。该函数由应用了 -c 选项的 dbwrite 命令行实用程序使

用。

原型原型原型原型 short DBCreateWriteFile ( const a_writefile * writefile );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Write File 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Write File 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "DBChangeWriteFile 函数 " 第 321 页

"DBStatusWriteFile 函数 " 第 328 页

"a_writefile 结构 " 第 364 页

参数参数参数参数 说明说明说明说明

create-db 指向 "a_create_db 结构 " 第 340 页 的指针

参数参数参数参数 说明说明说明说明

writefile 指向 "a_writefile 结构 " 第 364 页 的指针

323

Page 338: Adaptive Server Anywhere

DBTools 函数

DBCrypt 函数函数函数函数

函数函数函数函数 加密数据库文件。该函数由应用了 -e 选项的 dbinit 命令行实用程序

使用。

原型原型原型原型 short DBCrypt ( const a_crypt_db * crypt-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关加密数据库的信息,请参阅 "ASA 数据库管理指南 > 数据库管理实

用程序 > 使用 dbinit 实用程序创建数据库 "。

另请参阅另请参阅另请参阅另请参阅 "a_crypt_db 结构 " 第 342 页

DBErase 函数函数函数函数

函数函数函数函数 消除数据库文件和 / 或事务日志文件。该函数由 dberase 命令行实用

程序使用。

原型原型原型原型 short DBErase ( const an_erase_db * erase-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Erase 实用程序及其功能的信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > Erase 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "an_erase_db 结构 " 第 349 页

参数参数参数参数 说明说明说明说明

crypt-db 指向 "a_crypt_db 结构 " 第 342 页 的指针

参数参数参数参数 说明说明说明说明

erase-db 指向 "an_erase_db 结构 " 第 349 页 的指针

324

Page 339: Adaptive Server Anywhere

第 8 章 数据库工具接口

DBExpand 函数函数函数函数

函数函数函数函数 解压缩数据库文件。该函数由 dbexpand 命令行实用程序使用。

原型原型原型原型 short DBExpand ( const an_expand_db * expand-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Uncompression 实用程序及其功能的信息,请参阅 "ASA 数据库管

理指南 > 数据库管理实用程序 > Uncompression 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "an_expand_db 结构 " 第 350 页

DBInfo 函数函数函数函数

函数函数函数函数 返回有关数据库文件的信息。该函数由 dbinfo 命令行实用程序使用。

原型原型原型原型 short DBInfo ( const a_db_info * db-info );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Information 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Information 实用程序 "。

参数参数参数参数 说明说明说明说明

expand_db 指向 "an_expand_db 结构 " 第 350 页 的指针

参数参数参数参数 说明说明说明说明

db-info 指向 "a_db_info 结构 " 第 345 页 的指针

325

Page 340: Adaptive Server Anywhere

DBTools 函数

另请参阅另请参阅另请参阅另请参阅 "DBInfoDump 函数 " 第 326 页

"DBInfoFree 函数 " 第 326 页

"a_db_info 结构 " 第 345 页

DBInfoDump 函数函数函数函数

函数函数函数函数 返回有关数据库文件的信息。该函数由应用了 -u 选项的 dbinfo 命令

行实用程序使用。

原型原型原型原型 short DBInfoDump ( const a_db_info * db-info );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Information 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Information 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "DBInfo 函数 " 第 325 页

"DBInfoFree 函数 " 第 326 页

"a_db_info 结构 " 第 345 页

DBInfoFree 函数函数函数函数

函数函数函数函数 在调用 DBInfoDump 函数之后被调用以释放资源。

原型原型原型原型 short DBInfoFree ( const a_db_info * db-info );

参数参数参数参数 说明说明说明说明

db-info 指向 "a_db_info 结构 " 第 345 页 的指针

326

Page 341: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Information 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Information 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "DBInfo 函数 " 第 325 页

"DBInfoDump 函数 " 第 326 页

"a_db_info 结构 " 第 345 页

DBLicense 函数函数函数函数

函数函数函数函数 被调用以修改或报告数据库服务器的许可信息。

原型原型原型原型 short DBLicense ( const a_db_lic_info * db-lic-info );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Information 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Information 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_dblic_info 结构 " 第 347 页

参数参数参数参数 说明说明说明说明

db-info 指向 "a_db_info 结构 " 第 345 页 的指针

参数参数参数参数 说明说明说明说明

db-lic-info 指向 "a_dblic_info 结构 " 第 347 页 的指针

327

Page 342: Adaptive Server Anywhere

DBTools 函数

DBStatusWriteFile 函数函数函数函数

函数函数函数函数 获取写文件的状态。该函数由应用了 -s 选项的 dbwrite 命令行实用程

序使用。

原型原型原型原型 short DBStatusWriteFile ( const a_writefile * writefile );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Write File 实用程序及其功能的信息,请参阅 "ASA 数据库管理指

南 > 数据库管理实用程序 > Write File 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "DBChangeWriteFile 函数 " 第 321 页

"DBCreateWriteFile 函数 " 第 323 页

"a_writefile 结构 " 第 364 页

DBSynchronizeLog 函数函数函数函数

函数函数函数函数 将数据库与 MobiLink 同步服务器同步。

原型原型原型原型 short DBSynchronizeLog( const a _sync_db * sync-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关可访问的功能的信息,请参阅 "MobiLink 同步技术用户指南 > Adaptive Server Anywhere 客户端 > 启动同步 "。

参数参数参数参数 说明说明说明说明

writefile 指向 "a_writefile 结构 " 第 364 页 的指针

参数参数参数参数 说明说明说明说明

sync-db 指向 "a_sync_db 结构 " 第 352 页 的指针

328

Page 343: Adaptive Server Anywhere

第 8 章 数据库工具接口

DBToolsFini 函数函数函数函数

函数函数函数函数 当应用程序用完 DBTools 库后,计数器值减一并释放资源。

原型原型原型原型 short DBToolsFini ( const a_dbtools_info * dbtools-info );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 DBToolsFini 函数必须在任何使用 DBTools 接口的应用程序末尾被调

用,否则会导致遗失内存资源。

另请参阅另请参阅另请参阅另请参阅 "DBToolsInit 函数 " 第 329 页

"a_dbtools_info 结构 " 第 348 页

DBToolsInit 函数函数函数函数

函数函数函数函数 准备要使用的 DBTools 库。

原型原型原型原型 short DBToolsInit t( const a_dbtools_info * dbtools-info );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 DBToolsInit 函数的主要用途是装载 Adaptive Server Anywhere 语言 DLL。语言 DLL 包含 DBTools 内部使用的本地化版本的错误消息和提

示。

参数参数参数参数 说明说明说明说明

dbtools-info 指向 "a_dbtools_info 结构 " 第 348 页 的指针

参数参数参数参数 说明说明说明说明

dbtools-info 指向 "a_dbtools_info 结构 " 第 348 页 的指针

329

Page 344: Adaptive Server Anywhere

DBTools 函数

DBToolsInit 函数必须在任何使用 DBTools 接口的应用程序启动时以及

在调用任何其它 DBTools 函数之前被调用。

示例示例示例示例 • 下面的代码示例阐释了如何初始化和清除 DBTools:

a_dbtools_infoinfo;short ret;memset( &info, 0, sizeof( a_dbtools_info) );info.errorrtn = (MSG_CALLBACK)MakeProcInstance( (FARPROC)MyErrorRtn, hInst );// initialize DBToolsret = DBToolsInit( &info );if( ret != EXIT_OKAY ) {// DLL initialization failed...}// call some DBTools routines . . ....// cleanup the DBTools dllDBToolsFini( &info );

另请参阅另请参阅另请参阅另请参阅 "DBToolsFini 函数 " 第 329 页

"a_dbtools_info 结构 " 第 348 页

DBToolsVersion 函数函数函数函数

函数函数函数函数 返回 DBTools 库的版本号。

原型原型原型原型 short DBToolsVersion ( void );

返回值返回值返回值返回值 一个短整数,指示 DBTools 库的版本号。

用法用法用法用法 使用 DBToolsVersion 函数来检查 DBTools 库不比应用程序开发所针对的

库旧。尽管应用程序可针对较新版本的 DBTools 运行,但是它们不能针

对较旧版本的 DBTools 运行。

另请参阅另请参阅另请参阅另请参阅 " 版本号和兼容性 " 第 315 页

330

Page 345: Adaptive Server Anywhere

第 8 章 数据库工具接口

DBTranslateLog 函数函数函数函数

函数函数函数函数 将事务日志文件翻译为 SQL。该函数由 dbtran 命令行实用程序使用。

原型原型原型原型 short DBTranslateLog ( const a_translate_log * translate-log );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Log Translation 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > Log Translation 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_translate_log 结构 " 第 357 页

DBTruncateLog 函数函数函数函数

函数函数函数函数 截断事务日志文件。该函数由 dbbackup 命令行实用程序使用。

原型原型原型原型 short DBTruncateLog ( const a_truncate_log * truncate-log );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Backup 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据库

管理实用程序 > Backup 实用程序 "

另请参阅另请参阅另请参阅另请参阅 "a_truncate_log 结构 " 第 358 页

参数参数参数参数 说明说明说明说明

translate-log 指向 "a_translate_log 结构 " 第 357 页 的指针

参数参数参数参数 说明说明说明说明

truncate-log 指向 "a_truncate_log 结构 " 第 358 页 的指针

331

Page 346: Adaptive Server Anywhere

DBTools 函数

DBUnload 函数函数函数函数

函数函数函数函数 卸载数据库。该函数由 dbunload 命令行实用程序使用,还可由 SQL Remote 的 dbxtract 实用程序使用。

原型原型原型原型 short DBUnload ( const an_unload_db * unload-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Unload 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据库

管理实用程序 > Unload 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "an_unload_db 结构 " 第 359 页

DBUpgrade 函数函数函数函数

函数函数函数函数 升级数据库文件。该函数由 dbupgrade 命令行实用程序使用。

原型原型原型原型 short DBUpgrade ( const an_upgrade_db * upgrade-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Upgrade 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据库

管理实用程序 > Upgrade 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "an_upgrade_db 结构 " 第 361 页

参数参数参数参数 说明说明说明说明

unload-db 指向 "an_unload_db 结构 " 第 359 页 的指针

参数参数参数参数 说明说明说明说明

upgrade-db 指向 "an_upgrade_db 结构 " 第 361 页 的指针

332

Page 347: Adaptive Server Anywhere

第 8 章 数据库工具接口

DBValidate 函数函数函数函数

函数函数函数函数 校验所有或部分数据库。该函数由 dbvalid 命令行实用程序使用。

原型原型原型原型 short DBValidate ( const a_validate_db * validate-db );

参数参数参数参数

返回值返回值返回值返回值 一个返回代码,如 " 软件组件的返回代码 " 第 313 页中所列。

用法用法用法用法 有关 Validation 实用程序的信息,请参阅 "ASA 数据库管理指南 > 数据

库管理实用程序 > Validation 实用程序 "。

另请参阅另请参阅另请参阅另请参阅 "a_validate_db 结构 " 第 362 页

参数参数参数参数 说明说明说明说明

validate-db 指向 "a_validate_db 结构 " 第 362 页 的指针

333

Page 348: Adaptive Server Anywhere

DBTools 结构

DBTools 结构结构结构结构

本节列出用于与 DBTools 库交换信息的结构。这些结构按字母顺序列

出。

许多结构元素与相应实用程序上的命令行选项相对应。例如,几个结构具有名为 quiet 的成员,它们可采用值 0 或 1。该成员与由许多实用程序

使用的 quiet 操作 (-q) 命令行选项相对应。

a_backup_db 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库执行备份任务所需的信息。

语法语法语法语法 typedef struct a_backup_db { unsigned short version; const char * output_dir; const char * connectparms; const char * startline; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field backup_database : 1; a_bit_field backup_logfile : 1; a_bit_field backup_writefile : 1; a_bit_field no_confirm : 1; a_bit_field quiet : 1; a_bit_field rename_log : 1; a_bit_field truncate_log : 1; a_bit_field rename_local_log: 1; const char * hotlog_filename; char backup_interrupted; } a_backup_db;

参数参数参数参数

成员成员成员成员 说明说明说明说明

Version DBTools 版本号

output_dir 输出目录的路径。例如:"c:\backup"

334

Page 349: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBBackup 函数 " 第 320 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管

理指南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

confirmrtn 用于确认操作的回调例程

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

backup_database 备份数据库文件 (1) 或不备份 (0)

backup_logfile 备份事务日志文件 (1) 或不备份 (0)

backup_writefile 如果写文件正被使用,则备份数据库写文件 (1) 或不备

份 (0)

no_confirm 在进行确认 (0) 或不进行确认 (1) 的情况下运行

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

rename_log 重命名事务日志

truncate_log 删除事务日志

rename_local_log 重命名事务日志的本地备份

hotlog_filename 活动备份文件的文件名

backup_interrupted 指示该操作已被中断

成员成员成员成员 说明说明说明说明

335

Page 350: Adaptive Server Anywhere

DBTools 结构

a_change_log 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库执行 dblog 任务所需的信息。

语法语法语法语法 typedef struct a_change_log { unsigned short version; const char * dbname; const char * logname; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; a_bit_field query_only : 1; a_bit_field quiet : 1; a_bit_field mirrorname_present : 1; a_bit_field change_mirrorname : 1; a_bit_field change_logname : 1; a_bit_field ignore_ltm_trunc : 1; a_bit_field ignore_remote_trunc : 1; a_bit_field set_generation_number : 1; a_bit_field ignore_dbsync_trunc : 1; const char * mirrorname; unsigned short generation_number; const char * key_file; char * zap_current_offset; char * sap_starting_offset; char * encryption_key; } a_change_log;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号

dbname 数据库文件名

logname 事务日志的名称。如果设置为 NULL,则没有日志

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

query_only 如果为 1,则只显示事务日志的名称。如果为 0,则容许更改日志名。

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

336

Page 351: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBChangeLogName 函数 " 第 320 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

mirrorname_present 设置为 1。指示 DBTools 的版本足够新,可以支持

镜像名字段

change_mirrorname 如果为 1,则容许更改日志镜像的名称

change_logname 如果为 1,则容许更改事务日志的名称

ignore_ltm_trunc 当使用 " 日志传送管理器 " 时,执行与 dbcc settrunc( 'ltm', 'gen_id', n )" 复制服务器 " 功能相同的

功能:有关 dbcc 的信息,请参阅 " 复制服务器 " 文档

ignore_remote_trunc 用于 SQL Remote。重新设置用于 DELETE_OLD_LOGS 选项的偏移量,允许事务日

志在不再需要时被删除

set_generation_number 当使用 " 日志传送管理器 " 时,在备份被还原以便

设置世代号之后使用

ignore_dbsync_trunc 当使用 dbmlsync 时,重新设置用于 DELETE_OLD_LOGS 选项的偏移量,允许事务日

志在不再需要时被删除

mirrorname 事务日志镜像文件的新名称

generation_number 新的世代号。与 set_generation_number 一起使用

key_file 用于保存加密密钥的文件

zap_current_offset 将当前的偏移量更改为指定的值。这只用于在卸载并重装之后重新设置事务日志以便与 dbremote 或 dbmlsync 设置相匹配。

zap_starting_offset 将起始偏移量更改为指定的值。这只用于在卸载并重装之后重新设置事务日志以便与 dbremote 或 dbmlsync 设置相匹配。

encryption_key 数据库文件的加密密钥。

成员成员成员成员 说明说明说明说明

337

Page 352: Adaptive Server Anywhere

DBTools 结构

a_compress_db 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库执行数据库压缩任务所需的信息。

语法语法语法语法 typedef struct a_compress_db { unsigned short version; const char * dbname; const char * compress_name; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field display_free_pages : 1; a_bit_field quiet : 1; a_bit_field record_unchanged : 1; a_compress_stats * stats; MSG_CALLBACK confirmrtn; a_bit_field noconfirm : 1; const char * encryption_key } a_compress_db;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号

dbname 要压缩的数据库的文件名

compress_name 已压缩的数据库的文件名

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

display_free_pages 显示空闲页信息。

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

record_unchanged 设置为 1。指示 a_compress_stats 结构足够新,可以有 unchanged 成员

a_compress_stats 指向 a_compress_stats 类型的结构的指针。如果该成

员不是 NULL 且 display_free_pages 不是零,则填充

该指针。

338

Page 353: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBCompress 函数 " 第 322 页

"a_compress_stats 结构 " 第 339 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_compress_stats 结构结构结构结构

函数函数函数函数 保存有关压缩数据库文件的统计信息。

语法语法语法语法 typedef struct a_compress_stats { a_stats_line tables; a_stats_line indices; a_stats_line other; a_stats_line free; a_stats_line total; a_sql_int32 free_pages; a_sql_int32 unchanged; } a_compress_stats;

参数参数参数参数

confirmrtn 用于确认操作的回调例程

noconfirm 在进行确认 (0) 或不进行确认 (1) 的情况下运行

encryption_key 数据库文件的加密密钥。

成员成员成员成员 说明说明说明说明

成员成员成员成员 说明说明说明说明

tables 保存有关表的压缩信息

indices 保存有关索引的压缩信息

other 保存其它压缩信息

free 保存有关可用空间的信息

total 保存全部压缩信息

free_pages 保存有关空闲页的信息

339

Page 354: Adaptive Server Anywhere

DBTools 结构

另请参阅另请参阅另请参阅另请参阅 "DBCompress 函数 " 第 322 页

"a_compress_db 结构 " 第 338 页

a_create_db 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库创建数据库所需的信息。

语法语法语法语法 typedef struct a_create_db { unsigned short version; const char * dbname; const char * logname; const char * startline; short page_size; const char * default_collation; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; short database_version; char verbose; a_bit_field blank_pad : 2; a_bit_field respect_case : 1; a_bit_field encrypt : 1; a_bit_field debug : 1; a_bit_field dbo_avail : 1; a_bit_field mirrorname_present : 1; a_bit_field avoid_view_collisions : 1; short collation_id; const char * dbo_username; const char * mirrorname; const char * encryption_dllname; a_bit_field java_classes : 1; a_bit_field jconnect : 1; const char * data_store_type const char * encryption_key; const char * encryption_algorithm; const char * jdK_version; } a_create_db;

unchanged 压缩算法无法压缩的页数

成员成员成员成员 说明说明说明说明

340

Page 355: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号

dbname 数据库文件名

logname 新事务日志的名称

startline 用于启动数据库引擎的命令行。下面是启动行的示例:

"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

page_size 数据库的页面大小

default_collation 数据库的归类

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

database_version 数据库的版本号

verbose 在详细模式下运行

blank_pad 比较字符串时,将空白视为有效,并保存索引信息以反映这种情况

respect_case 使字符串比较区分大小写,并保存索引信息以反映这种情况

encrypt 加密数据库

debug 保留

dbo_avail 设置为 1。该数据库中存在 dbo 用户

mirrorname_present 设置为 1。指示 DBTools 的版本足够新,可以支持镜

像名字段。

avoid_view_collisions 忽略 Watcom SQL 兼容视图 SYS.SYSCOLUMNS 和 SYS.SYSINDEXES 的生成

collation_id 归类标识符

dbo_username 不再使用:设置为 NULL

341

Page 356: Adaptive Server Anywhere

DBTools 结构

另请参阅另请参阅另请参阅另请参阅 "DBCreate 函数 " 第 322 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_crypt_db 结构结构结构结构

函数函数函数函数 保存对由 dbinit 命令行实用程序使用的数据库文件进行加密所需的信

息。

语法语法语法语法 typedef struct a_crypt_db { const char _fd_ * dbname; const char _fd_ * dllname; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; char verbose; a_bit_field quiet : 1; a_bit_field debug : 1; } a_crypt_db;

参数参数参数参数

mirrorname 事务日志镜像的名称

encryption_dllname 用于对数据库进行加密的 DLL。

java_classes 创建启用了 Java 的数据库。

jconnect 包括 jConnect 所需的系统过程

data_store_type 保留。使用 NULL。

encryption_key 数据库文件的加密密钥。

encryption_algorithm AES 或 MDSR。

jdk_version dbinit -jdk 选项的某个值。

成员成员成员成员 说明说明说明说明

成员成员成员成员 说明说明说明说明

dbname 数据库文件的名称

342

Page 357: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBCrypt 函数 " 第 324 页

"ASA 数据库管理指南 > 数据库管理实用程序 > 使用 dbinit 实用程序创

建数据库 "

a_db_collation 结构结构结构结构

函数函数函数函数 保留使用 DBTools 库从数据库抽取归类序列所需的信息。

语法语法语法语法 typedef struct a_db_collation { unsigned short version; const char * connectparms; const char * startline; const char * collation_label; const char * filename; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; a_bit_field include_empty : 1; a_bit_field hex_for_extended : 1; a_bit_field replace : 1; a_bit_field quiet : 1; const char * input_filename; const char _fd_ * mapping_filename; } a_db_collation;

dllname 用于执行加密的 DLL 的名称

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

verbose 在详细模式下运行

quiet 在没有消息的情况下运行

debug 保留

成员成员成员成员 说明说明说明说明

343

Page 358: Adaptive Server Anywhere

DBTools 结构

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "DBCollate 函数 " 第 321 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

成员成员成员成员 说明说明说明说明

version DBTools 版本号

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管

理指南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

confirmrtn 用于确认操作的回调例程

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

include_empty 在归类序列空隙写空映射

hex_for_extended 使用两位数的十六进制数字来表示高值字符

replace 在不确认操作的情况下运行

quiet 在没有消息的情况下运行

input_filename 输入归类定义

mapping_filename syscollationmapping 输出

344

Page 359: Adaptive Server Anywhere

第 8 章 数据库工具接口

a_db_info 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库返回 dbinfo 信息所需的信息。

语法语法语法语法 typedef struct a_db_info { unsigned short version; MSG_CALLBACK errorrtn; const char * dbname; unsigned short dbbufsize; char * dbnamebuffer; unsigned short logbufsize; char * lognamebuffer; unsigned short wrtbufsize; char * wrtnamebuffer; a_bit_field quiet : 1; a_bit_field mirrorname_present : 1; a_sysinfo sysinfo; unsigned long free_pages; a_bit_field compressed : 1; const char * connectparms; const char * startline; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field page_usage : 1; a_table_info * totals; unsigned long file_size; unsigned long unused_pages; unsigned long other_pages; unsigned short mirrorbufsize; char * mirrornamebuffer; char * unused_field; char * collationnamebuffer; unsigned short collationnamebufsize; char * classesversionbuffer; unsigned short classesversionbufsize; } a_db_info;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号

errortrn 用于处理错误消息的回调例程

345

Page 360: Adaptive Server Anywhere

DBTools 结构

dbname 数据库文件的名称

dbbufsize dbnamebuffer 成员的长度

dbnamebuffer 数据库文件的名称

logbufsize lognamebuffer 成员的长度

lognamebuffer 事务日志文件的名称

wrtbufsize wrtnamebuffer 成员的长度

wrtnamebuffer 写文件的名称

quiet 在不确认消息的情况下运行

mirrorname_present 设置为 1。指示 DBTools 的版本足够新,可以支持镜

像名字段

sysinfo 指向 a_sysinfo 结构的指针

free_pages 空闲页数

compressed 如果已压缩,则为 1,否则为 0

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\Program Files\Sybase\SQL Anywhere 8\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管

理指南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:

"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

page_usage 如果报告页面使用统计,则为 1,否则为 0

totals 指向 a_table_info 结构的指针

成员成员成员成员 说明说明说明说明

346

Page 361: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBInfo 函数 " 第 325 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_dblic_info 结构结构结构结构

函数函数函数函数 保存包含许可信息的信息。使用此信息时必须严格遵守许可协议。

语法语法语法语法 typedef struct a_dblic_info { unsigned short version; char * exename; char * username; char * compname; char * platform_str; a_sql_int32 nodecount; a_sql_int32 conncount; a_license_type type; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn;

file_size 数据库文件的大小

unused_pages 未使用的页数

other_pages 既不是表页又不是索引页的页数

mirrorbufsize mirrornamebuffer 成员的长度

mirrornamebuffer 事务日志镜像的名称

collationnamebuffer 数据库归类的名称和标签( 大大小为 128+1)

collationnamebufsize collationnamebuffer 成员的长度

classesversionbuffer 已安装的 Java 类的 JDK 版本,如 1.1.3、 1.1.8、 1.3,如果数据库中没有安装 Java 类,则为空字符串 (

大大小为 10+1)

classesversionbufsize classesversionbuffer 成员的长度

成员成员成员成员 说明说明说明说明

347

Page 362: Adaptive Server Anywhere

DBTools 结构

a_bit_field quiet : 1; a_bit_field query_only : 1; } a_dblic_info;

参数参数参数参数

a_dbtools_info 结构结构结构结构

函数函数函数函数 保存有关开始和完成使用 DBTools 库所需的信息。

语法语法语法语法 typedef struct a_dbtools_info { MSG_CALLBACK errorrtn; } a_dbtools_info;

成员成员成员成员 说明说明说明说明

version DBTools 版本号

exename 可执行文件名

username 获得许可的用户名

compname 获得许可的公司名

platform_str 操作系统:WinNT、 NLM 或 UNIX

nodecount 许可的节点数。

conncount 必须为 1000000L

type 请参阅 lictype.h 以查看其值

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

query_only 如果为 1,则只显示许可信息。如果为 0,则容许更改该信

348

Page 363: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "DBToolsFini 函数 " 第 329 页

"DBToolsInit 函数 " 第 329 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

an_erase_db 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库消除数据库所需的信息。

语法语法语法语法 typedef struct an_erase_db { unsigned short version; const char * dbname; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; a_bit_field quiet : 1; a_bit_field erase : 1; const char * encryption_key; } an_erase_db;

参数参数参数参数

成员成员成员成员 说明说明说明说明

errorrtn 用于处理错误消息的回调例程

成员成员成员成员 说明说明说明说明

version DBTools 版本号

dbname 要消除的数据库文件的名称

confirmrtn 用于确认操作的回调例程

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

erase 在不进行确认 (1) 或进行确认 (0) 的情况下消除

349

Page 364: Adaptive Server Anywhere

DBTools 结构

另请参阅另请参阅另请参阅另请参阅 "DBErase 函数 " 第 324 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

an_expand_db 结构结构结构结构

函数函数函数函数 保存使用 DBTools 库扩展数据库所需的信息。

语法语法语法语法 typedef struct an_expand_db { unsigned short version; const char * compress_name; const char * dbname; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field quiet : 1; MSG_CALLBACK confirmrtn; a_bit_field noconfirm : 1; const char * key_file; const char * encryption_key; } an_expand_db;

参数参数参数参数

encryption_key 数据库文件的加密密钥。

成员成员成员成员 说明说明说明说明

成员成员成员成员 说明说明说明说明

version DBTools 版本号

compress_name 压缩数据库文件的名称

dbname 数据库文件的名称

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

350

Page 365: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBExpand 函数 " 第 325 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_name 结构结构结构结构

函数函数函数函数 保存名称的链接列表。这由需要名称列表的其它结构使用。

语法语法语法语法 typedef struct a_name { struct a_name * next; char name[1]; } a_name, * p_name;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_translate_log 结构 " 第 357 页

"a_validate_db 结构 " 第 362 页

"an_unload_db 结构 " 第 359 页

confirmrtn 用于确认操作的回调例程

noconfirm 在进行确认 (0) 或不进行确认 (1) 的情况下运行

key_file 用于保存加密密钥的文件

encryption_key 数据库文件的加密密钥。

成员成员成员成员 说明说明说明说明

成员成员成员成员 说明说明说明说明

next 指向列表中下一个 a_name 结构的指针

name 名称

p_name 执行上一个 a_name 结构的指针

351

Page 366: Adaptive Server Anywhere

DBTools 结构

a_stats_line 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库压缩和扩展数据库所需的信息。

语法语法语法语法 typedef struct a_stats_line { long pages; long bytes; long compressed_bytes; } a_stats_line;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_compress_stats 结构 " 第 339 页

a_sync_db 结构结构结构结构

函数函数函数函数 保存 dbmlsync 实用程序使用 DBTools 库时所需的信息。

语法语法语法语法 typedef struct a_sync_db { unsigned short version; char _fd_ * connectparms; char _fd_ * publication; const char _fd_ * offline_dir; char _fd_ * extended_options; char _fd_ * script_full_path; const char _fd_ * include_scan_range; const char _fd_ * raw_file; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK logrtn; a_SQL_uint32 debug_dump_size; a_SQL_uint32 dl_insert_width; a_bit_field verbose : 1;

成员成员成员成员 说明说明说明说明

pages 页数

bytes 解压缩的数据库的字节数

compressed_bytes 压缩数据库的字节数

352

Page 367: Adaptive Server Anywhere

第 8 章 数据库工具接口

a_bit_field debug : 1; a_bit_field debug_dump_hex : 1; a_bit_field debug_dump_char : 1; a_bit_field debug_page_offsets : 1; a_bit_field use_hex_offsets : 1; a_bit_field use_relative_offsets : 1; a_bit_field output_to_file : 1; a_bit_field output_to_mobile_link : 1; a_bit_field dl_use_put : 1; a_bit_field dl_use_upsert : 1; a_bit_field kill_other_connections : 1; a_bit_field retry_remote_behind : 1; a_bit_field ignore_debug_interrupt : 1; SET_WINDOW_TITLE_CALLBACK set_window_title_rtn; char * default_window_title; MSG_QUEUE_CALLBACK msgqueuertn; MSG_CALLBACK progress_msg_rtn; SET_PROGRESS_CALLBACK progress_index_rtn; char ** argv; char ** ce_argv; a_bit_field connectparms_allocated : 1; a_bit_field entered_dialog : 1; a_bit_field used_dialog_allocation : 1; a_bit_field ignore_scheduling : 1; a_bit_field ignore_hook_errors : 1; a_bit_field changing_pwd : 1; a_bit_field prompt_again : 1; a_bit_field retry_remote_ahead : 1; a_bit_field rename_log : 1; a_bit_field hide_conn_str : 1; a_bit_field hide_ml_pwd : 1; a_bit_field delay_ml_disconn : 1; a_SQL_uint32 dlg_launch_focus; char _fd_ * mlpassword; char _fd_ * new_mlpassword; char _fd_ * verify_mlpassword; a_SQL_uint32 pub_name_cnt; char ** pub_name_list; USAGE_CALLBACK usage_rtn; a_sql_uint32 hovering_frequency; a_bit_short ignore_hovering : 1; a_bit_short verbose_upload : 1; a_bit_short verbose_upload_data : 1; a_bit_short verbose_download : 1; a_bit_short verbose_download_data : 1; a_bit_short autoclose : 1;

353

Page 368: Adaptive Server Anywhere

DBTools 结构

a_bit_short ping : 1; a_bit_short _unused : 9; char _fd_ * encryption_key; a_syncpub _fd_ * upload_defs; char _fd_ * log_file_name; char _fd_ * user_name; } a_sync_db;

参数参数参数参数 这些参数与可从 dbmlsync 命令行实用程序访问的功能相对应。

有关更多说明,请参阅 dbtools.h 头文件。

有关更多信息,请参阅 "MobiLink 同步技术用户指南 > MobiLink 同步

服务器选项 > MobiLink 同步客户端 "。

另请参阅另请参阅另请参阅另请参阅 "DBSynchronizeLog 函数 " 第 328 页

a_syncpub 结构结构结构结构

函数函数函数函数 保存 dbmlsync 实用程序所需的信息。

语法语法语法语法 typedef struct a_syncpub { struct a_syncpub _fd_ * next; char _fd_ * pub_name; char _fd_ * ext_opt; a_bit_field alloced_by_dbsync: 1; } a_syncpub;

参数参数参数参数

成员成员成员成员 说明说明说明说明

a_syncpub 指向列表中下一个节点的指针, NULL 表示 后一

个节点

pub_name 为该 -n 选项指定的发布名称。命令行上 -n 后面就

是这个字符串。

ext_opt 使用 -eu 选项指定的扩展选项

encryption 如果对数据库进行了加密,则为 1,否则为 0

354

Page 369: Adaptive Server Anywhere

第 8 章 数据库工具接口

a_sysinfo 结构结构结构结构

函数函数函数函数 保存有关 dbinfo 和 dbunload 实用程序使用 DBTools 库时所需的信

息。

typedef struct a_sysinfo { a_bit_field valid_data : 1; a_bit_field blank_padding : 1; a_bit_field case_sensitivity : 1; a_bit_field encryption : 1; char default_collation[11]; unsigned short page_size; } a_sysinfo;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_db_info 结构 " 第 345 页

alloced_by_dbsync FALSE,对于在 dbtool8.dll 中创建的节点除

成员成员成员成员 说明说明说明说明

成员成员成员成员 说明说明说明说明

valid_date 用于指示是否设置下列值的位字段

blank_padding 如果在该数据库中使用空白填充,则为 1,否则为 0

case_sensitivity 如果数据库区分大小写,则为 1,否则为 0

encryption 如果对数据库进行了加密,则为 1,否则为 0

default_collation

数据库的归类序列

page_size 数据库的页面大小

355

Page 370: Adaptive Server Anywhere

DBTools 结构

a_table_info 结构结构结构结构

函数函数函数函数 保存有关 a_db_info 结构所需表的信息。

语法语法语法语法 typedef struct a_table_info { struct a_table_info * next; unsigned short table_id; unsigned long table_pages; unsigned long index_pages; unsigned long table_used; unsigned long index_used; char * table_name; a_sql_uint32 table_used_pct; a_sql_uint32 index_used_pct; } a_table_info;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_db_info 结构 " 第 345 页

成员成员成员成员 说明说明说明说明

next 列表中的下一个表

table_id 该表的 ID 号

table_pages 表页数

index_pages 索引页数

table_used 表页中使用的字节数

index_used 索引页中使用的字节数

table_name 表的名称

table_used_pct 表空间的使用百分比

index_used_pct 索引空间的使用百分比

356

Page 371: Adaptive Server Anywhere

第 8 章 数据库工具接口

a_translate_log 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库转换事务日志所需的信息。

语法语法语法语法 typedef struct a_translate_log { unsigned short version; const char * logname; const char * sqlname; p_name userlist; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; char userlisttype; a_bit_field remove_rollback : 1; a_bit_field ansi_SQL : 1; a_bit_field since_checkpoint: 1; a_bit_field omit_comments : 1; a_bit_field replace : 1; a_bit_field debug : 1; a_bit_field include_trigger_trans : 1; a_bit_field comment_trigger_trans : 1; unsigned long since_time; const char _fd_ * reserved_1; const char _fd_ * reserved_2; a_sql_uint32 debug_dump_size; a_bit_field debug_sql_remote : 1; a_bit_field debug_dump_hex : 1; a_bit_field debug_dump_char : 1; a_bit_field debug_page_offsets : 1; a_bit_field reserved_3 : 1; a_bit_field use_hex_offsets : 1; a_bit_field use_relative_offsets : 1; a_bit_field include_audit : 1; a_bit_field chronological_order : 1; a_bit_field force_recovery : 1; a_bit_field include_subsets : 1; a_bit_field force_chaining : 1; a_sql_uint32 recovery_ops; a_sql_uint32 recovery_bytes; const char _fd_ * include_source_sets; const char _fd_ * include_destination_sets; const char _fd_ * include_scan_range; const char _fd_ * repserver_users; const char _fd_ * include_tables; const char _fd_ * include_publications;

357

Page 372: Adaptive Server Anywhere

DBTools 结构

const char _fd_ * queueparms; a_bit_field generate_reciprocals :1; a_bit_field match_mode :1; const char _fd_ * match_pos; MSG_CALLBACK statusrtn; const char _fd_ * encryption_key; a_bit_field show_undo :1; const char _fd_ * logs_dir; } a_translate_log;

参数参数参数参数 这些参数与可从 dbtran 命令行实用程序访问的功能相对应。

有关更多说明,请参阅 dbtools.h 头文件。

另请参阅另请参阅另请参阅另请参阅 "DBTranslateLog 函数 " 第 331 页

"a_name 结构 " 第 351 页

"dbtran_userlist_type 枚举 " 第 367 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_truncate_log 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库截断事务日志所需的信息。

语法语法语法语法 typedef struct a_truncate_log { unsigned short version; const char * connectparms; const char * startline; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; a_bit_field quiet : 1; char truncate_interrupted; } a_truncate_log;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号。

358

Page 373: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBTruncateLog 函数 " 第 331 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

an_unload_db 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库卸载数据库或者为 SQL Remote 抽取远程数据

库所需的信息。指示由 dbxtract SQL Remote Extraction 实用程序使用

的字段。

语法语法语法语法 typedef struct an_unload_db { unsigned short version; const char * connectparms; const char * startline; const char * temp_dir; const char * reload_filename; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; MSG_CALLBACK confirmrtn; char unload_type; char verbose;

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管

理指南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

truncate_interrupted 指示该操作已被中断

成员成员成员成员 说明说明说明说明

359

Page 374: Adaptive Server Anywhere

DBTools 结构

a_bit_field unordered : 1; a_bit_field no_confirm : 1; a_bit_field use_internal_unload : 1; a_bit_field dbo_avail : 1; a_bit_field extract : 1; a_bit_field table_list_provided : 1; a_bit_field exclude_tables : 1; a_bit_field more_flag_bits_present : 1; a_sysinfo sysinfo; const char * remote_dir; const char * dbo_username; const char * subscriber_username; const char * publisher_address_type; const char * publisher_address; unsigned short isolation_level; a_bit_field start_subscriptions : 1; a_bit_field exclude_foreign_keys : 1; a_bit_field exclude_procedures : 1; a_bit_field exclude_triggers : 1; a_bit_field exclude_views : 1; a_bit_field isolation_set : 1; a_bit_field include_where_subscribe : 1; a_bit_field debug : 1; p_name table_list; a_bit_short escape_char_present : 1; a_bit_short view_iterations_present : 1; unsigned short view_iterations; char escape_char; char _fd_ * reload_connectparms; char _fd_ * reload_db_filename; a_bit_field output_connections:1; char unload_interrupted; a_bit_field replace_db:1; const char _fd_ * locale; const char _fd_ * site_name; const char _fd_ * template_name; a_bit_field preserve_ids:1; a_bit_field exclude_hooks:1; char _fd_ * reload_db_logname; const char _fd_ * encryption_key; const char _fd_ * encryption_algorithm; a_bit_field syntax_version_7:1; a_bit_field remove_java:1; } an_unload_db;

360

Page 375: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数 这些参数与可从 dbunload、 dbxtract 和 mlxtract 命令行实用程序

访问的功能相对应。

有关更多说明,请参阅 dbtools.h 头文件。

另请参阅另请参阅另请参阅另请参阅 "DBUnload 函数 " 第 332 页

"a_name 结构 " 第 351 页

"dbunload 类型枚举 " 第 367 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

an_upgrade_db 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库升级数据库所需的信息。

语法语法语法语法 typedef struct an_upgrade_db { unsigned short version; const char * connectparms; const char * startline; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field quiet : 1; a_bit_field dbo_avail : 1; const char * dbo_username; a_bit_field java_classes : 1; a_bit_field jconnect : 1; a_bit_field remove_java : 1; a_bit_field java_switch_specified : 1; const char * jdk_version; } an_upgrade_db;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号。

361

Page 376: Adaptive Server Anywhere

DBTools 结构

另请参阅另请参阅另请参阅另请参阅 "DBUpgrade 函数 " 第 332 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

a_validate_db 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库校验数据库所需的信息。

语法语法语法语法 typedef struct a_validate_db { unsigned short version; const char * connectparms;

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管理指

南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:"c:\asa\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

dbo_avail 设置为 1。指示 DBTools 的版本足够新,可以支持 dbo_username 字段

dbo_username dbo 所使用的名称

java_classes 将数据库升级到启用 Java 的数据库

jconnect 升级数据库以包括 jConnect 过程

remove_java 升级数据库,删除 Java 功能

jdk_version dbinit -jdk 选项的某个值。

成员成员成员成员 说明说明说明说明

362

Page 377: Adaptive Server Anywhere

第 8 章 数据库工具接口

const char * startline; p_name tables; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; MSG_CALLBACK statusrtn; a_bit_field quiet : 1; a_bit_field index : 1; a_validate_type type; } a_validate_db;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "DBValidate 函数 " 第 333 页

"a_name 结构 " 第 351 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

成员成员成员成员 说明说明说明说明

version DBTools 版本号。

connectparms 连接到数据库所需的参数。它们采用如下所示的连接字符串形式:

"UID=DBA;PWD=SQL;DBF=c:\asa\asademo.db"

要了解各种连接字符串选项,请参阅 "ASA 数据库管理指南 > 连接到数据库 > 连接参数 "

startline 用于启动数据库引擎的命令行。下面是启动行的示例:"c:\Program Files\Sybase\SA\win32\dbeng8.exe"

如果该成员为 NULL,则使用缺省启动行

tables 指向表名的链接列表的指针

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

statusrtn 用于处理状态消息的回调例程

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

index 校验索引

type 请参阅 "a_validate_type 枚举 " 第 368 页

363

Page 378: Adaptive Server Anywhere

DBTools 结构

a_writefile 结构结构结构结构

函数函数函数函数 保存有关使用 DBTools 库管理数据库写文件所需的信息。

语法语法语法语法 typedef struct a_writefile { unsigned short version; const char * writename; const char * wlogname; const char * dbname; const char * forcename; MSG_CALLBACK confirmrtn; MSG_CALLBACK errorrtn; MSG_CALLBACK msgrtn; char action; a_bit_field quiet : 1; a_bit_field erase : 1; a_bit_field force : 1; a_bit_field mirrorname_present : 1; const char * wlogmirrorname; a_bit_field make_log_and_mirror_names: 1; const char * encryption_key; } a_writefile;

参数参数参数参数

成员成员成员成员 说明说明说明说明

version DBTools 版本号

writename 写文件的名称

wlogname 只在创建写文件时使用

dbname 在更改和创建写文件时使用

forcename 强制的文件名引用

confirmrtn 用于确认操作的回调例程。只在创建写文件时使用

errorrtn 用于处理错误消息的回调例程

msgrtn 用于处理信息消息的回调例程

action 保留以供 Sybase 使用

quiet 在不打印消息 (1) 或打印消息 (0) 的情况下运行

364

Page 379: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "DBChangeWriteFile 函数 " 第 321 页

"DBCreateWriteFile 函数 " 第 323 页

"DBStatusWriteFile 函数 " 第 328 页

有关回调函数的更多信息,请参阅 " 使用回调函数 " 第 313 页。

erase 只用于创建写文件。在不进行确认 (1) 或进行确认 (0) 的情况下消除

force 如果为 1,强制写文件指向命名文件

mirrorname_present 只在创建时使用。设置为 1。指示 DBTools 的版本足

够新,可以支持镜像名字段

wlogmirrorname 事务日志镜像的名称

make_log_and_mirror_names

如果为 TRUE,则使用 wlogname 和 wlogmirrorname 中的值来确定文件名。

encryption_key 数据库文件的加密密钥。

成员成员成员成员 说明说明说明说明

365

Page 380: Adaptive Server Anywhere

DBTools 枚举类型

DBTools 枚举类型枚举类型枚举类型枚举类型

本节列出由 DBTools 库使用的枚举类型。这些枚举按字母顺序列出。

详细枚举详细枚举详细枚举详细枚举

函数函数函数函数 指定输出的量。

语法语法语法语法 enum { VB_QUIET, VB_NORMAL, VB_VERBOSE };

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_create_db 结构 " 第 340 页

"an_unload_db 结构 " 第 359 页

空白填充枚举空白填充枚举空白填充枚举空白填充枚举

函数函数函数函数 在 "a_create_db 结构 " 第 340 页 中用于指定 blank_pad 的值。

语法语法语法语法 enum { NO_BLANK_PADDING, BLANK_PADDING };

值值值值 说明说明说明说明

VB_QUIET 无输出

VB_NORMAL 一般输出量

VB_VERBOSE 详细输出,有助于进行调试

366

Page 381: Adaptive Server Anywhere

第 8 章 数据库工具接口

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_create_db 结构 " 第 340 页

dbtran_userlist_type 枚举枚举枚举枚举

函数函数函数函数 用户列表的类型,由 "a_translate_log 结构 " 第 357 页 使用。

语法语法语法语法 typedef enum dbtran_userlist_type { DBTRAN_INCLUDE_ALL, DBTRAN_INCLUDE_SOME, DBTRAN_EXCLUDE_SOME } dbtran_userlist_type;

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "a_translate_log 结构 " 第 357 页

dbunload 类型枚举类型枚举类型枚举类型枚举

函数函数函数函数 正执行的卸载的类型,由 "an_unload_db 结构 " 第 359 页 使用。

语法语法语法语法 enum { UNLOAD_ALL, UNLOAD_DATA_ONLY, UNLOAD_NO_DATA };

值值值值 说明说明说明说明

NO_BLANK_PADDING 不使用空白填充

BLANK_PADDING 使用空白填充

值值值值 说明说明说明说明

DBTRAN_INCLUDE_ALL 包括所有用户的操作

DBTRAN_INCLUDE_SOME 只包括所提供用户列表中用户的操作

DBTRAN_EXCLUDE_SOME 排除所提供用户列表中用户进行的操作

367

Page 382: Adaptive Server Anywhere

DBTools 枚举类型

参数参数参数参数

另请参阅另请参阅另请参阅另请参阅 "an_unload_db 结构 " 第 359 页

a_validate_type 枚举枚举枚举枚举

函数函数函数函数 正执行的校验的类型,由 "a_validate_db 结构 " 第 362 页 使用。

语法语法语法语法 typedef enum { VALIDATE_NORMAL = 0, VALIDATE_DATA, VALIDATE_INDEX, VALIDATE_EXPRESS, VALIDATE_FULL } a_validate_type;

参数参数参数参数

值值值值 说明说明说明说明

UNLOAD_ALL 卸载数据和模式

UNLOAD_DATA_ONLY 卸载数据,不卸载模式

UNLOAD_NO_DATA 只卸载模式

值值值值 说明说明说明说明

VALIDATE_NORMAL 只用缺省检查进行校验。

VALIDATE_DATA 除了缺省检查,还用数据检查进行校验。

VALIDATE_INDEX 除了缺省检查,还用索引检查进行校验。

VALIDATE_EXPRESS 除了缺省检查和数据检查,还用快速检查进行校验。

VALIDATE_FULL 除了缺省检查,还用数据检查和索引检查进行校验。

368

Page 383: Adaptive Server Anywhere

第 8 章 数据库工具接口

另请参阅另请参阅另请参阅另请参阅 "ASA 数据库管理指南 > 数据库管理实用程序 > 使用 dbvalid 实用程序校

验数据库 "

"ASA SQL 参考手册 > SQL 语句 > VALIDATE TABLE 语句 "

369

Page 384: Adaptive Server Anywhere

DBTools 枚举类型

370

Page 385: Adaptive Server Anywhere

第 9 章

OLE DB 和和和和 ADO 编程接口编程接口编程接口编程接口

关于本章关于本章关于本章关于本章 本章介绍如何使用 Adaptive Server Anywhere 的 OLE DB 接口。

许多使用 OLE DB 接口的应用程序都是通过 Microsoft ActiveX 数据对象 (ADO) 编程模型来使用,而非直接使用。本章还介绍通过 Adaptive Server Anywhere 进行 ADO 编程。

371

Page 386: Adaptive Server Anywhere

OLE DB 介绍

OLE DB 介绍介绍介绍介绍

OLE DB 是 Microsoft 的数据访问模型。它使用组件对象模型 (COM) 接口,与 ODBC 不同的是, OLE DB 假定数据源使用的不是 SQL 查询处

理器。

Adaptive Server Anywhere 包括一个名为 ASAProv 的 OLE DB 提供程提供程提供程提供程

序序序序。该提供程序可用于当前的 Windows 和 Windows CE 平台。

您还可以结合使用 " 用于 ODBC 的 Microsoft OLE DB 提供程序

"(MSDASQL) 和 Adaptive Server Anywhere ODBC 驱动程序来访问 Adaptive Server Anywhere。

使用 Adaptive Server Anywhere OLE DB 提供程序具有以下几个优点:

• 某些功能 (如通过游标更新)不能通过 OLE DB/ODBC Bridge 来使用。

• 如果您使用 Adaptive Server Anywhere OLE DB 提供程序,则在部

署过程中无需 ODBC。

• MSDASQL 允许 OLE DB 客户端用于任何 ODBC 驱动程序,但不

保证您可以使用每个 ODBC 驱动程序的全部功能。而使用 Adaptive Server Anywhere 提供程序,您可以从 OLE DB 编程环境

完全访问 Adaptive Server Anywhere 的全部功能。

支持的平台支持的平台支持的平台支持的平台

Adaptive Server Anywhere OLE DB 提供程序设计为使用 OLE DB 2.5 和更高版本。对于 Windows CE 及其后续版本, OLE DB 提供程序是为 ADOCE 3.0 和更高版本设计的。

ADOCE 是 Microsoft ADO for Windows CE SDK,它为用 Windows CE Toolkits for Visual Basic 5.0 和 Visual Basic 6.0 开发的应用程序提供数据

库功能。

有关受支持的平台的更多信息,请参阅 "SQL Anywhere Studio 介绍 > 教程:使用 InfoMaker 创建报告 > 操作系统版本 "。

372

Page 387: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

分布式事务分布式事务分布式事务分布式事务

OLE DB 驱动程序可在分布式事务环境中用作资源管理器。

有关更多信息,请参阅 " 三层计算和分布式事务 " 第 397 页。

373

Page 388: Adaptive Server Anywhere

利用 Adaptive Server Anywhere 进行 ADO 编程

利用利用利用利用 Adaptive Server Anywhere 进行进行进行进行 ADO 编程编程编程编程

ADO (ActiveX 数据对象)是一种通过 Automation 接口暴露的数据访

问对象模型,它允许客户端应用程序在事先不了解对象的情况下,在运行时发现该对象的方法和属性。 Automation 接口允许脚本语言 (如 Visual Basic)使用标准的数据访问对象模型。 ADO 使用 OLE DB 提供

数据访问。

使用 Adaptive Server Anywhere OLE DB 提供程序,您可以从 ADO 编程

环境完全访问 Adaptive Server Anywhere 的全部功能。

本节说明了在从 Visual Basic 使用 ADO 时如何执行基本任务。它不是使

用 ADO 进行编程的完整指南。

本节中的代码示例可在下列文件中找到:

有关在 ADO 中进行编程的信息,请参阅开发工具的文档。

有关如何使用 ADO 和 Visual Basic 来访问 Adaptive Server Anywhere 数据库中数据的详细讨论,请参阅白皮书 Accessing Data in Adaptive Server Anywhere Using ADO and Visual Basic ,该文可在以下网址找到:

http://www.sybase.com/detail?id=1017429。

用用用用 Connection 对象连接到数据库对象连接到数据库对象连接到数据库对象连接到数据库

本节介绍一个用于连接到数据库的简单的 Visual Basic 例程。

示例代码示例代码示例代码示例代码 通过将名为 Command1 的命令按钮放在窗体上,并将该例程粘贴到它

的 Click 事件中,可以尝试执行该例程。运行程序并单击该按钮,即可

建立连接然后断开连接。

开发工具开发工具开发工具开发工具 示例示例示例示例

Microsoft Visual Basic 6.0

Samples\ASA\VBSampler\vbsampler.vbp

Microsoft eMbedded Visual Basic 3.0

Samples\ASA\ADOCE\OLEDB_PocketPC.ebp

374

Page 389: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

Private Sub cmdTestConnection_Click() ' Declare variables Dim myConn As New ADODB.Connection Dim myCommand As New ADODB.Command Dim cAffected As Long On Error GoTo HandleError ' Establish the connection myConn.Provider = "ASAProv" myConn.ConnectionString = _ "Data Source=ASA 8.0 Sample" myConn.Open MsgBox "Connection succeeded" myConn.Close Exit Sub HandleError: MsgBox "Connection failed" Exit SubEnd Sub

注意注意注意注意 该示例执行下列任务:

• 声明例程中使用的变量。

• 使用 Adaptive Server Anywhere OLE DB 提供程序建立到示例数据

库的连接。

• 使用 Command 对象执行一条简单语句,该语句可在数据库服务器

窗口上显示消息。

• 关闭连接。

如果安装了 ASAProv 提供程序,则它自行注册。注册过程包括在注册

表的 COM 部分创建注册表项,以便 ADO 可以在 ASAProv 提供程序被

调用时找到该 DLL。如果您更改了 DLL 的位置,则必须进行注册。

❖ 注册注册注册注册 OLE DB 提供程序:提供程序:提供程序:提供程序:

1 打开命令提示。

2 更改到安装 OLE DB 提供程序的目录。

375

Page 390: Adaptive Server Anywhere

利用 Adaptive Server Anywhere 进行 ADO 编程

3 输入以下命令以注册该提供程序:

regsvr32 dboledb8.dll

有关使用 OLE DB 连接到数据库的详细信息,请参阅 "ASA 数据库管理

指南 > 连接到数据库 > 使用 OLE DB 连接到数据库 "。

用用用用 Command 对象执行语句对象执行语句对象执行语句对象执行语句

本节介绍一个向数据库发送简单 SQL 语句的简单例程。

示例代码示例代码示例代码示例代码 通过将名为 Command2 的命令按钮放在窗体上,并将该例程粘贴到它

的 Click 事件中,可以尝试执行该例程。运行程序并单击该按钮以便建

立连接,在数据库服务器窗口上显示消息,然后断开连接。

Private Sub cmdUpdate_Click() ' Declare variables Dim myConn As New ADODB.Connection Dim myCommand As New ADODB.Command Dim cAffected As Long ' Establish the connection myConn.Provider = "ASAProv" myConn.ConnectionString = _ "Data Source=ASA 8.0 Sample" myConn.Open 'Execute a command myCommand.CommandText = _ "update customer set fname='Liz' where id=102" Set myCommand.ActiveConnection = myConn myCommand.Execute cAffected MsgBox CStr(cAffected) +

" rows affected.", vbInformation myConn.CloseEnd Sub

注意注意注意注意 在建立连接之后,示例代码创建 Command 对象,将它的 CommandText 属性设置为更新语句,并将它的 ActiveConnection 属性设置为当前连

接。然后,它执行更新语句,并在消息框中显示受更新操作影响的行数。

在本示例中,更新在执行之后立即被发送到数据库并被提交。

有关在 ADO 内使用事务的信息,请参阅 " 使用事务 " 第 380 页。

376

Page 391: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

您还可以通过游标执行更新。

有关更多信息,请参阅 " 通过游标更新数据 " 第 379 页。

用用用用 Recordset 对象查询数据库对象查询数据库对象查询数据库对象查询数据库

ADO Recordset 对象表示查询的结果集。您可以使用它查看数据库中的

数据。

示例代码示例代码示例代码示例代码 通过将名为 cmdQuery 的命令按钮放在窗体上,并将该例程粘贴到它的 Click 事件中,可以尝试执行该例程。运行程序并单击该按钮以便建立

连接,在数据库服务器窗口上显示消息,执行查询并在消息框中显示前几行,然后断开连接。

Private Sub cmdQuery_Click()' Declare variables Dim myConn As New ADODB.Connection Dim myCommand As New ADODB.Command Dim myRS As New ADODB.Recordset On Error GoTo ErrorHandler: ' Establish the connection myConn.Provider = "ASAProv" myConn.ConnectionString = _ "Data Source=ASA 8.0 Sample" myConn.CursorLocation = adUseServer myConn.Mode = adModeReadWrite myConn.IsolationLevel = adXactCursorStability myConn.Open 'Execute a query Set myRS = New Recordset myRS.CacheSize = 50 myRS.Source = "Select * from customer" myRS.ActiveConnection = myConn myRS.CursorType = adOpenKeyset myRS.LockType = adLockOptimistic myRS.Open 'Scroll through the first few results myRS.MoveFirst For i = 1 To 5

377

Page 392: Adaptive Server Anywhere

利用 Adaptive Server Anywhere 进行 ADO 编程

MsgBox myRS.Fields("company_name"), vbInformation myRS.MoveNext Next myRS.Close myConn.Close Exit SubErrorHandler: MsgBox Error(Err) Exit SubEnd Sub

注意注意注意注意 本示例中的 Recordset 对象保存对 Customer 表执行查询所得的结果。

For 循环滚动浏览前几行并显示每一行的 company_name 值。

这是一个从 ADO 使用游标的简单示例。

有关从 ADO 使用游标的更高级示例,请参阅 " 使用 Recordset 对象 " 第378 页。

使用使用使用使用 Recordset 对象对象对象对象

在使用 Adaptive Server Anywhere 时, ADO Recordset 代表一个游标。

可以通过在打开 Recordset 对象之前声明 Recordset 对象的 CursorType 属性来选择游标类型。所选游标类型控制着可对 Recordset 执行的操

作,并会对性能产生影响。

游标类型游标类型游标类型游标类型 Adaptive Server Anywhere 支持的游标类型集在 " 游标属性 " 第 25 页中进

行说明。 ADO 有它自己的游标类型命名规则。

下面列出可用的游标类型、相应的游标类型常量以及与它们等价的 Adaptive Server Anywhere 类型:

ADO 游标类型游标类型游标类型游标类型 ADO 常量常量常量常量Adaptive Server Anywhere 类型类型类型类型

动态游标 adOpenDynamic 动态滚动游标

键集游标 adOpenKeyset 滚动游标

静态游标 adOpenStatic 不敏感游标

378

Page 393: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

有关如何选择适合应用程序的游标类型的信息,请参阅 "选择游标类型 " 第 25 页。

示例代码示例代码示例代码示例代码 下列代码集为 ADO Recordset 对象设置游标类型:

Dim myRS As New ADODB.RecordsetmyRS.CursorType = adOpenDynamic

通过游标更新数据通过游标更新数据通过游标更新数据通过游标更新数据

Adaptive Server Anywhere OLE DB 提供程序允许您通过游标更新结果

集。该功能不能通过 MSDASQL 提供程序实现。

更新记录集更新记录集更新记录集更新记录集 可以通过记录集来更新数据库。

Private Sub Command6_Click() Dim myConn As New ADODB.Connection Dim myRS As New ADODB.Recordset Dim SQLString As String ' Connect myConn.Provider = "ASAProv" myConn.ConnectionString = _ "Data Source=ASA 8.0 Sample" myConn.Open myConn.BeginTrans SQLString = "Select * from customer" myRS.Open SQLString, _

myConn, adOpenDynamic, adLockBatchOptimistic If myRS.BOF And myRS.EOF Then MsgBox "Recordset is empty!", _ 16, "Empty Recordset" Else MsgBox "Cursor type: " + _ CStr(myRS.CursorType), vbInformation myRS.MoveFirst For i = 1 To 3 MsgBox "Row: " + CStr(myRS.Fields("id")), _

只进游标 adOpenForwardOnly 非滚动游标

ADO 游标类型游标类型游标类型游标类型 ADO 常量常量常量常量Adaptive Server Anywhere 类型类型类型类型

379

Page 394: Adaptive Server Anywhere

利用 Adaptive Server Anywhere 进行 ADO 编程

vbInformation If i = 2 Then myRS.Update "City", "Toronto" myRS.UpdateBatch End If myRS.MoveNext Next i' myRS.MovePrevious myRS.Close End If myConn.CommitTrans myConn.CloseEnd Sub

注意注意注意注意 如果对记录集使用 adLockBatchOptimistic 设置,则 myRS.Update 方法

不会对数据库本身进行任何更改,而是会更新 Recordset 的本地副本。

myRS.UpdateBatch 方法对数据库服务器进行更新,但是不提交更改,

因为它位于事务内部。如果在事务外部激活 UpdateBatch 方法,则更改

将被提交。

myConn.CommitTrans 方法提交所做的更改。 Recordset 对象在此之前

已被关闭,因此不存在数据的本地副本是否发生更改的问题。

使用事务使用事务使用事务使用事务

在缺省情况下,您使用 ADO 对数据库进行的任何更改都会在执行时被

立即提交。这包括显式更新以及对 Recordset 执行的 UpdateBatch 方法。但是,上一节说明您可以通过对 Connection 对象使用 BeginTrans 和 RollbackTrans 或 CommitTrans 方法来使用事务。

事务隔离级别是作为 Connection 对象的属性设置的。 IsolationLevel 属性可具有下列值:

ADO 隔离级别隔离级别隔离级别隔离级别 常量常量常量常量 ASA 级别级别级别级别

未指定 adXactUnspecified 不适用。设置为 0

混沌 adXactChaos 不支持。设置为 0

浏览 adXactBrowse 0

380

Page 395: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

有关隔离级别的更多信息,请参阅 "ASA SQL 用户指南 > 使用事务和隔

离级别 > 隔离级别和一致性 "。

未提交的读操作 adXactReadUncommitted 0

游标稳定性 adXactCursorStability 1

已提交的读操作 adXactReadCommitted 1

可重复的读操作 adXactRepeatableRead 2

已隔离 adXactIsolated 3

可序列化 adXactSerializable 3

ADO 隔离级别隔离级别隔离级别隔离级别 常量常量常量常量 ASA 级别级别级别级别

381

Page 396: Adaptive Server Anywhere

支持的 OLE DB 接口

支持的支持的支持的支持的 OLE DB 接口接口接口接口

OLE DB API 由一组接口组成。下表介绍 Adaptive Server Anywhere OLE DB 驱动程序中对每个接口的支持。

接口接口接口接口 用途用途用途用途 限制限制限制限制

IAccessor 定义客户端内存和数据存储值之间的捆绑。

不支持 DBACCESSOR_PASSBYREF。不支持 DBACCESSOR_OPTIMIZED。

IAlterIndexIAlterTable

变更表、索引和列。 不支持。

IChapteredRowset 分段的行集允许以单独的段访问行集中的行。

不支持。 Adaptive Server Anywhere 不支

持分段的行集。

IColumnsInfo 获得有关行集的列的简单信息。

不适用于 CE。

IColumnsRowset 获得有关行集内可选元数据列的信息,并获得列元数据的行集。

不适用于 CE。

ICommand 执行 SQL 命令。 不支持调用。IcommandProperties:带有 DBPROPSET_PROPERTIESINERROR 的 GetProperties,用于查

找尚未设置的属性。

ICommandPersist 保持命令对象(而非任何活动行集)的状态。随后可使用 PROCEDURES 或 VIEWS 行集枚举这些

持久性命令对象。

不适用于 CE。

ICommandPrepare 准备命令。 不适用于 CE。

382

Page 397: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

ICommandProperties 为由命令创建的行集设置 " 行集 " 属性。

常用于指定行集应当支持的接口。

支持。

ICommandText 为 ICommand 设置 SQL 命令文本。

只支持 DBGUID_DEFAULT SQL 方言。

IcommandWithParameters 为命令设置或获取参数信息。

不支持以标量值的矢量形式存储的参数。不支持 BLOB 参数。

不适用于 CE。

IConvertType 支持。在 CE 上受限制。

IDBAsynchNotifyIDBAsyncStatus

异步处理。在数据源初始化、填充行集等的异步处理时,向客户端通知事件。

不支持。

IDBCreateCommand 从会话创建命令。 支持。

IDBCreateSession 从数据源对象创建会话。

支持。

IDBDataSourceAdmin 创建 / 破坏 / 修改数据

源对象 — 由客户端使

用的 COM 对象。该接

口不用于管理数据存储区(数据库)。

不支持。

IDBInfo 查找该提供程序所特有的关键字的信息(即,查找非标准的 SQL 关键字)。

还查找有关文字、文本匹配查询中使用的特殊字符、以及其它文字信息。

不适用于 CE。

接口接口接口接口 用途用途用途用途 限制限制限制限制

383

Page 398: Adaptive Server Anywhere

支持的 OLE DB 接口

IDBInitialize 初始化数据源对象和枚举器。

不适用于 CE。

IDBProperties 管理数据源对象或枚举器的属性。

不适用于 CE。

IDBSchemaRowset 以标准格式(行集)获取有关系统表的信息。

不适用于 CE。

IErrorInfoIErrorLookupIErrorRecords

支持 ActiveX 错误对

象。

不适用于 CE。

IGetDataSource 将接口指针返回会话的数据源对象。

支持。

IIndexDefinition 在数据存储区创建或删除索引。

不支持。

IMultipleResults 从命令检索多个结果(行集或行计数)。

支持。

IOpenRowset 按照数据库表的名称访问数据库表的非 SQL 方式。

支持。支持按照表名打开表,不支持按照 GUID 打开表。

IParentRowset 访问分段 / 层次结构行

集。

不支持。

IRowset 访问行集。 支持。

IRowsetChange 允许更改行集数据,并将所做更改反映回数据存储区。尚未执行用于二进制大对象 (Blob) 的InsertRow/SetData。

不适用于 CE。

IRowsetChapterMember 访问分段 / 层次结构行

集。

不支持。

IRowsetCurrentIndex 动态更改行集的索引。 不支持。

接口接口接口接口 用途用途用途用途 限制限制限制限制

384

Page 399: Adaptive Server Anywhere

第 9 章 OLE DB 和 ADO 编程接口

IRowsetFind 在行集中查找与指定值匹配的行。

不支持。

IRowsetIdentity 比较行的句柄。 不支持。

IRowsetIndex 访问数据库索引。 不支持。

IRowsetInfo 查找有关行集属性的信息或者查找创建了行集的对象。

不适用于 CE。

IRowsetLocate 使用书签定位到行集的行上。

不适用于 CE。

IRowsetNotify 为行集事件提供 COM 回调接口。

支持。

IRowsetRefresh 获取事务可看到的数据的 新值。

不支持。

IRowsetResynch 旧的 OLEDB 1.x 接口,被 IRowsetRefresh 替代。

不支持。

IRowsetScroll 滚动浏览行集以抓取行数据。

不支持。

IRowsetUpdate 延迟对行集数据的更改,直到 Update 被调

用。

支持。不适用于 CE。

IRowsetView 使用现有行集上的视图。

不支持。

ISequentialStream 检索二进制大对象 (Blob) 列。

只支持读取。不支持 对该接口执行 SetData。不适用于 CE。

ISessionProperties 获得会话属性信息。 支持。

ISourcesRowset 获得数据源对象和枚举器的行集。

不适用于 CE。

ISQLErrorInfoISupportErrorInfo

支持 ActiveX 错误对

象。

在 CE 上为可选接口。

接口接口接口接口 用途用途用途用途 限制限制限制限制

385

Page 400: Adaptive Server Anywhere

支持的 OLE DB 接口

ITableDefinitionITableDefinitionWithConstraints

用约束来创建、删除和变更表。

不适用于 CE。

ITransaction 提交或中止事务。 并非所有的标志都受支持。不适用于 CE。

ITransactionJoin 支持分布式事务。 并非所有的标志都受支持。不适用于 CE。

ITransactionLocal 处理会话事务。并非所有的标志都受支持。

不适用于 CE。

ITransactionOptions 获得或设置事务的选项。

不适用于 CE。

IViewChapter 使用现有行集上的视图,专用于对行应用后处理过滤 / 排序。

不支持。

IViewFilter 将行集的内容限制为与条件集相匹配的行。

不支持。

IViewRowset 在打开行集时,将行集的内容限制为与条件集相匹配的行。

不支持。

IViewSort 对视图应用排序顺序。 不支持。

接口接口接口接口 用途用途用途用途 限制限制限制限制

386

Page 401: Adaptive Server Anywhere

第 10 章

Open Client 接口接口接口接口

关于本章关于本章关于本章关于本章 本章介绍用于 Adaptive Server Anywhere 的 Open Client 编程接口。

Open Client 应用程序开发的主要文档为 Open Client 文档,您可从

Sybase 获得。本章主要用于介绍 Adaptive Server Anywhere 的特性,而

不是 Open Client 应用程序编程的详尽指南。

387

Page 402: Adaptive Server Anywhere

建立 Open Client 应用程序的要求

建立建立建立建立 Open Client 应用程序的要求应用程序的要求应用程序的要求应用程序的要求

要运行 Open Client 应用程序,您必须在它运行的计算机上安装和配置 Open Client 组件。这些组件可以作为您安装的其它 Sybase 产品的一部

分,或者您也可以随 Adaptive Server Anywhere 一起安装这些库,这取

决于许可协议条款的规定。

Open Client 应用程序不需要在运行数据库服务器的计算机上有任何 Open Client 组件。

要生成 Open Client 应用程序,您需要 Open Client 的开发版本,这可由 Sybase 提供。

缺省情况下, Adaptive Server Anywhere 数据库创建时是不区分大小写

的,而 Adaptive Server Enterprise 数据库是区分大小写的。

有关与 Adaptive Server Anywhere 一起运行 Open Client 应用程序的更多

信息,请参阅 "ASA 数据库管理指南 > 将 Adaptive Server Anywhere 用作 Open Server"。

388

Page 403: Adaptive Server Anywhere

第 10 章 Open Client 接口

数据类型映射数据类型映射数据类型映射数据类型映射

Open Client 有自已的内部数据类型,它们在某些细节上与 Adaptive Server Anywhere 中提供的数据类型有所区别。出于这个原因,Adaptive Server Anywhere 会在 Open Client 应用程序使用的数据类型和 Adaptive Server Anywhere 中的数据类型之间,对某些类型进行内部映射。

要建立 Open Client 应用程序,您需要 Open Client 的开发版本。要使用 Open Client 应用程序,则必须在它运行的计算机上安装和配置 Open Client 运行版本。

Adaptive Server Anywhere 服务器不需要任何外部通信运行版本即可支持 Open Client 应用程序。

每种 Open Client 数据类型都映射到了 Adaptive Server Anywhere 相对等

的数据类型。 Adaptive Server Anywhere 支持所有的 Open Client 数据类

型。

在在在在 Open Client 中没中没中没中没

有直接对等项的有直接对等项的有直接对等项的有直接对等项的 Adaptive Server Anywhere 数据类型数据类型数据类型数据类型

下表列出了在 Adaptive Server Anywhere 中受到支持、而在 Open Client 中没有直接对等项的数据类型的映射。

ASA 数据类型数据类型数据类型数据类型 Open Client 数据类型数据类型数据类型数据类型

unsigned short int

unsigned int bigint

unsigned bigint bigint

date smalldatetime

time smalldatetime

serialization longbinary

java longbinary

string varchar

timestamp struct datetime

389

Page 404: Adaptive Server Anywhere

数据类型映射

数据类型映射中的范围限制数据类型映射中的范围限制数据类型映射中的范围限制数据类型映射中的范围限制

某些数据类型在 Adaptive Server Anywhere 中与在 Open Client 中的范围

不同。这种情况下,检索或插入数据过程中可能会发生溢出错误。

下表列出了可映射到 Adaptive Server Anywhere 数据类型、但是在可能

值的范围上具有某些限制的 Open Client 应用程序数据类型。

在多数情况下, Open Client 数据类型会映射到 Adaptive Server Anywhere 数据类型,后者可以具有的值范围更大。因此,可能会出现

这样的情况:向 Adaptive Server Anywhere 传递的值将被接受并存储在

数据库中,而这个值对于 Open Client 应用程序来说太大,无法读取。

示例示例示例示例 例如, Open Client MONEY 和 SMALLMONEY 数据类型不会超过它们

底层的 Adaptive Server Anywhere 实现的整个数字范围。因此,

Adaptive Server Anywhere 列中的值有可能会超出 Open Client 数据类型 MONEY 的界限。当客户端通过 Adaptive Server Anywhere 读取这样有

问题的值时,就会生成错误。

时间戳时间戳时间戳时间戳 当 Open Client TIMESTAMP 值在 Adaptive Server Anywhere 中传递时,

该数据类型的 Adaptive Server Anywhere 实现与它的 Adaptive Server Enterprise 实现不同。在 Adaptive Server Anywhere 中,该值被映射到

数据类型数据类型数据类型数据类型Open Client 下限下限下限下限

Open Client 上上上上限限限限

ASA 下限下限下限下限 ASA 上限上限上限上限

MONEY -922 377 203 685 477.5808

922 377 203 685 477.5807

-1e15 + 0.0001

1e15 -0.0001

SMALLMONEY -214 748.3648

214 748.3647

-214 748.3648

214 748.3647

DATETIME Jan 1, 1753 Dec 31, 9999

Jan 1, 0001 Dec 31, 9999

SMALLDATETIME

Jan 1, 1900 June 6, 2079

March 1, 1600

Dec 31, 7910

390

Page 405: Adaptive Server Anywhere

第 10 章 Open Client 接口

Adaptive Server Anywhere DATETIME 数据类型。在 Adaptive Server Anywhere 中,缺省值是 NULL,而且不保证其唯一性。而 Adaptive Server Enterprise 可确保该值会单纯地增加,因而是唯一的。

相比之下, Adaptive Server Anywhere TIMESTAMP 数据类型包含年、

月、日、时、分、秒和毫秒信息。另外,就所具有的可能值的范围而言, DATETIME 数据类型比由 Adaptive Server Anywhere 映射来的 Open Client 数据类型要大。

391

Page 406: Adaptive Server Anywhere

在 Open Client 应用程序中使用 SQL

在在在在 Open Client 应用程序中使用应用程序中使用应用程序中使用应用程序中使用 SQL

本节简要介绍了在 Open Client 应用程序中使用 SQL 的信息,特别是重

点说明了 Adaptive Server Anywhere 的特定问题。

有关概念的介绍,请参阅 " 在应用程序中使用 SQL" 第 9 页。有关完整

说明,请参阅您的 Open Client 文档。

执行执行执行执行 SQL 语句语句语句语句

将 SQL 语句包括在 Client Library 函数调用中可将该语句发送到数据库

中。例如,下面的两个调用将执行 DELETE 语句:

ret = ct_command(cmd, CS_LANG_CMD, "DELETE FROM employee WHERE emp_id=105" CS_NULLTERM, CS_UNUSED);ret = ct_send(cmd);

ct_command 函数的用途十分广泛。

使用准备好的语句使用准备好的语句使用准备好的语句使用准备好的语句

ct_dynamic 函数用于管理准备好的语句。此函数采用 type 参数说明您要

采取什么操作。

❖ 在在在在 Open Client 中使用准备好的语句:中使用准备好的语句:中使用准备好的语句:中使用准备好的语句:

1 使用带 CS_PREPARE type 参数的 ct_dynamic 函数准备语句。

2 使用 ct_param 设置语句参数。

3 使用带 CS_EXECUTE type 参数的 ct_dynamic 执行语句。

4 使用带 CS_DEALLOC type 参数的 ct_dynamic 释放与该语句相

关联的资源。

392

Page 407: Adaptive Server Anywhere

第 10 章 Open Client 接口

有关在 Open Client 中使用准备好的语句的更多信息,请参阅您的 Open Client 文档。

使用游标使用游标使用游标使用游标

ct_cursor 函数用于管理游标。此函数采用 type 参数说明您要采取什么操

作。

支持的游标类型支持的游标类型支持的游标类型支持的游标类型 并非 Adaptive Server Anywhere 支持的所有游标类型都能通过 Open Client 接口使用。不能通过 Open Client 使用滚动游标、动态滚动游标或

不敏感游标。

唯一性和可更新性是游标的两个属性。游标可以唯一 (每行都有主键或唯一性信息,无论应用程序是否使用它),也可以不唯一。游标可以是只读的,也可以是可更新的。如果游标是可更新的且不是唯一的,则性能会受到影响,这是因为在这种情况下不会预读行,不管 CS_CURSOR_ROWS 怎样设置都是如此 (请参阅下面内容)。

使用游标的步骤使用游标的步骤使用游标的步骤使用游标的步骤 与某些其它接口不同 (例如 " 嵌入式 SQL"), Open Client 会将游标与

一个以字符串表示的 SQL 语句相关联。嵌入式 SQL 首先准备语句,然

后使用语句句柄声明游标。

❖ 在在在在 Open Client 中使用游标:中使用游标:中使用游标:中使用游标:

1 要在 Open Client 中声明游标,您可以使用 ct_cursor,并将 CS_CURSOR_DECLARE 作为 type 参数。

2 声明游标之后,您可以控制每次使用 ct_cursor (以 CS_CURSOR_ROWS 作为 type 参数)从服务器读取行时有多少

行要预读到客户端。

在客户端存储预读的行会减少对服务器的调用,从而提高总体吞吐量,同时减少周转时间。预读的行不会立即传递到应用程序,而是存储在客户端的缓冲区内备用。

PREFETCH 数据库选项的设置控制其它接口行的预读。 Open Client 连接会忽略该设置。 CS_CURSOR_ROWS 设置对于非唯

一的、可更新的游标是忽略的。

393

Page 408: Adaptive Server Anywhere

在 Open Client 应用程序中使用 SQL

3 要在 Open Client 中打开游标,您可以使用 ct_cursor,并将 CS_CURSOR_OPEN 作为 type 参数。

4 使用 ct_fetch 可将每行读取到应用程序中。

5 使用带 CS_CURSOR_CLOSE 的 ct_cursor 可关闭游标。

6 在 Open Client 中,您还需要释放与游标相关联的资源。使用带 CS_CURSOR_DEALLOC 的 ct_cursor 可以释放资源。您还可以

使用带附加参数 CS_DEALLOC 的 CS_CURSOR_CLOSE 以一

个步骤完成这些操作。

通过游标修改行通过游标修改行通过游标修改行通过游标修改行

对于 Open Client,只要游标是用于单个表的,您就可以在游标中删除或

更新行。用户必须有更新表的权限,游标必须标记为更新。

❖ 通过游标修改行通过游标修改行通过游标修改行通过游标修改行

• 您可以不执行读取,而是分别使用带 CS_CURSOR_DELETE 或 CS_CURSOR_UPDATE 的 ct_cursor 来删除或更新游标的当前

行。

在 Open Client 应用程序中不能通过游标插入行。

在在在在 Open Client 中说明查询结果中说明查询结果中说明查询结果中说明查询结果

Open Client 处理结果集的方式与某些其它 Adaptive Server Anywhere 接口不同。

在嵌入式 SQL 和 ODBC 中,您说明说明说明说明查询或存储过程是为了设置变量的

正确数目和类型,以便接收结果。说明在语句本身上进行。

在 Open Client 中,您不需要说明语句,从服务器返回的每一行都可以

带有对其内容的说明。如果使用 ct_command 和 ct_send 执行语句,则

可以使用 ct_results 函数处理查询中所返回行的各个方面内容。

394

Page 409: Adaptive Server Anywhere

第 10 章 Open Client 接口

如果不想用这种逐行方式来处理结果集,您可以使用 ct_dynamic 来准备 SQL 语句,并使用 ct_describe 来说明结果集。这种方法更接近于其它接

口中 SQL 语句的说明方式。

395

Page 410: Adaptive Server Anywhere

Adaptive Server Anywhere 的已知 Open Client 限制

Adaptive Server Anywhere 的已知的已知的已知的已知 Open Client 限制限制限制限制

通过 Open Client 接口,您可以基本上以使用 Adaptive Server Enterprise 数据库的相同方式使用 Adaptive Server Anywhere 数据库。但还是有一

些限制,其中包括以下几条:

• 提交服务提交服务提交服务提交服务 :Adaptive Server Anywhere 不支持 Adaptive Server Enterprise 提交服务。

• 功能功能功能功能 :客户 / 服务器连接的功能功能功能功能决定了该连接所允许的客户端请

求和服务器响应的类型。不支持下列功能:

• CS_REG_NOTIF

• CS_CSR_ABS

• CS_CSR_FIRST

• CS_CSR_LAST

• CS_CSR_PREV

• CS_CSR_REL

• CS_DATA_BOUNDARY

• CS_DATA_SENSITIVITY

• CS_PROTO_DYNPROC

• CS_REQ_BCP

• 不支持安全选项,例如 SSL 和加密密码。

• Open Client 应用程序可以使用 TCP/IP 或者本地计算机具有的 NamedPipes 协议连接到 Adaptive Server Anywhere。

有关功能的更多信息,请参阅 《Open Server Server-Library C 参考

手册》。

396

Page 411: Adaptive Server Anywhere

第 11 章

三层计算和分布式事务三层计算和分布式事务三层计算和分布式事务三层计算和分布式事务

关于本章关于本章关于本章关于本章 本章说明如何在一个拥有应用程序服务器的三层环境中使用 Adaptive Server Anywhere。本章重点讲述如何在分布式事务中利用 Adaptive Server Anywhere。

397

Page 412: Adaptive Server Anywhere

简介

简介简介简介简介

您可以将 Adaptive Server Anywhere 作为数据库服务器或者 " 资源管理资源管理资源管理资源管理

器器器器 " 使用,参与到由事务服务器协调的分布式事务中。

在一个三层环境中,应用程序服务器位于客户端应用程序和一组资源管理器之间蜒这是一种常用的分布式事务环境。 Sybase EAServer 和其它

一些应用程序服务器也都是事务服务器。

Sybase EAServer 和 Microsoft Transaction Server 都使用 "Microsoft 分布

式事务处理协调器 "(DTC) 来协调事务。 Adaptive Server Anywhere 提供

了对 DTC 服务所控制的分布式事务的支持,因此,您可以将 Adaptive Server Anywhere 用于上述两种应用程序服务器中的任意一种,也可以

用于任何其它基于 DTC 模型的产品。

将 Adaptive Server Anywhere 集成到三层环境中时,大多数工作都需要

在应用程序服务器上完成。本章将介绍三层计算的概念和体系结构,并将概括讲述 Adaptive Server Anywhere 的有关功能。但本章不介绍如何

相应地配置您的应用程序服务器以使其能够使用 Adaptive Server Anywhere。有关更多信息,请参阅应用程序服务器的文档。

398

Page 413: Adaptive Server Anywhere

第 11 章 三层计算和分布式事务

三层计算体系结构三层计算体系结构三层计算体系结构三层计算体系结构

在三层计算中,应用程序逻辑保存在应用程序服务器 (如 Sybase EAServer)上,该服务器位于资源管理器和客户端应用程序之间。在许

多情况下,一个应用程序服务器可以访问多个资源管理器。在 Internet 中,客户端应用程序是基于浏览器的,而应用程序服务器通常是 Web 服务器扩展。

Sybase EAServer 以组件的形式存储应用程序逻辑,并使这些组件对客

户端应用程序可用。这些组件可以是 PowerBuilder 组件、 JavaBean,也

可以是 COM 组件。

有关更多信息,请参阅 Sybase EAServer 文档。

应用程序服务器

399

Page 414: Adaptive Server Anywhere

三层计算体系结构

三层计算中的分布式事务三层计算中的分布式事务三层计算中的分布式事务三层计算中的分布式事务

客户端应用程序或应用程序服务器使用一个事务处理数据库 (例如 Adaptive Server Anywhere)时,数据库外部并不需要事务逻辑;但是,

如果使用多个资源管理器,事务控制就必须包括事务所涉及的各种资源。应用程序服务器会向它们的客户应用程序提供事务逻辑,以保证操作集能够以原子方式执行。

许多事务服务器 (包括 Sybase EAServer)都使用 "Microsoft 分布式事

务处理协调器 "(DTC) 来向它们的客户端应用程序提供事务服务。 DTC 使用 "OLE 事务事务事务事务 ",而该事务又使用 " 两阶段提交两阶段提交两阶段提交两阶段提交 " 协议来协调涉及多

个资源管理器的事务。您必须安装 DTC,然后才能使用本章介绍的功

能。

分布式事务中的分布式事务中的分布式事务中的分布式事务中的 Adaptive Server Anywhere

Adaptive Server Anywhere 可以参与由 DTC 协调的事务,这就是说,您

可以在使用事务服务器 (例如 Sybase EAServer 或 Microsoft Transaction Server)的分布式事务中使用 Adaptive Server Anywhere 数据库。您还可

以直接在应用程序中使用 DTC 来协调多个资源管理器中的事务。

分布式事务词汇分布式事务词汇分布式事务词汇分布式事务词汇

本章假设您在一定程度上熟悉分布式事务。有关信息,请参阅您的事务服务器文档。本节介绍一些常用的术语。

• " 资源管理器资源管理器资源管理器资源管理器 " 是那些对事务中涉及的数据进行管理的服务。

在通过 OLE DB 或 ODBC 访问 Adaptive Server Anywhere 数据库服

务器时, Adaptive Server Anywhere 数据库服务器可以用作分布式

事务中的资源管理器。 ODBC 驱动程序和 OLE DB 提供程序用作

客户机上的资源管理器代理。

• 应用程序组件并不与资源管理器直接通信,但可以与 " 资源分发器资源分发器资源分发器资源分发器

" 通信,而资源分发器又管理与这些资源管理器的连接或连接池。

Adaptive Server Anywhere 支持两个资源分发器:ODBC 驱动程序

管理器和 OLE DB。

• 当事务组件请求数据库连接时 (使用资源管理器),应用程序服

务器会 " 征用征用征用征用 " 参与事务的每个数据库连接。 DTC 和资源分发器

执行征用过程。

400

Page 415: Adaptive Server Anywhere

第 11 章 三层计算和分布式事务

两阶段提交两阶段提交两阶段提交两阶段提交 分布式事务是使用两阶段提交管理的。当事务的工作完成时,事务管理器 (DTC) 会询问事务中征用的所有资源管理器是否准备提交该事务。此

阶段称为 " 准备准备准备准备 " 提交。

如果所有的资源管理器都响应:它们准备提交,那么, DTC 就会向每

个资源管理器发送一个提交请求,并对它的客户端响应:事务已经完成。如果有一个或多个资源管理器不响应,或者响应:它无法提交事务,那么,事务的所有工作将会通过所有资源管理器回退。

应用程序服务器如何使用应用程序服务器如何使用应用程序服务器如何使用应用程序服务器如何使用 DTC

Sybase EAServer 和 Microsoft Transaction Server 都是组件服务器。应用

程序逻辑以组件的形式保存,并且对客户端应用程序可用。

每个组件都有一个事务属性来指示组件参与事务的方式。创建组件的应用程序开发人员必须将事务的工作编为组件,即资源管理器连接,资源管理器连接是每个资源管理器负责的对数据的操作。但是,应用程序开发人员不需要将事务管理逻辑添加到组件中。一旦设置了事务属性来指示组件需要事务管理, EAServer 就会使用 DTC 来征用事务并管理两阶

段提交过程。

401

Page 416: Adaptive Server Anywhere

三层计算体系结构

分布式事务体系结构分布式事务体系结构分布式事务体系结构分布式事务体系结构

下面的图示阐明了分布式事务的体系结构。在此例中,资源管理器代理可以是 ODBC 也可以是 OLE DB。

此例中使用了一个资源分发器。应用程序服务器请求 DTC 准备事务。

DTC 和资源分发器征用事务中的每个连接。每个资源管理器必须与 DTC 和数据库都保持联系,这样才能进行工作,才能在需要时向 DTC 通报它的事务状态。

DTCDTC

DTC资源管理器

代理资源管理器

代理

应用程序服务器

客户端系统

服务器系统 1

服务器系统 2

402

Page 417: Adaptive Server Anywhere

第 11 章 三层计算和分布式事务

DTC 服务必须在每个计算机上都运行,才能操作分布式事务。您可以

从 Windows 的控制面板中的 " 服务 " 图标控制 DTC 服务; DTC 服务的

名称为 MSDTC。

有关更多信息,请参阅您的 DTC 或 EAServer 文档。

403

Page 418: Adaptive Server Anywhere

使用分布式事务

使用分布式事务使用分布式事务使用分布式事务使用分布式事务

当 Adaptive Server Anywhere 在分布式事务中被征用时,它会将事务控

制交给事务服务器, Adaptive Server Anywhere 确保它不会执行任何隐

式事务管理。 Adaptive Server Anywhere 参与分布式事务时会自动规定

以下条件:

• 如果自动提交处于使用状态,则它自动关闭。

• 在分布式事务过程中不允许数据定义语句 (其提交属于意外情

况)。

• 由应用程序直接 (而不是通过事务协调器)发布到 Adaptive Server Anywhere 的显式 COMMIT 或 ROLLBACK 会将生成错误。

但是该事务并不中止。

• 一个连接一次只能参与一个分布式事务。

• 当连接被征用到分布式事务中时一定不能有未提交的操作。

DTC 隔离级别隔离级别隔离级别隔离级别

DTC 具有一组隔离级别,隔离级别是由应用程序服务器指定的。这些

隔离级别以如下方式映射 Adaptive Server Anywhere 隔离级别:

DTC 隔离级别隔离级别隔离级别隔离级别Adaptive Server Anywhere 隔离级别隔离级别隔离级别隔离级别

ISOLATIONLEVEL_UNSPECIFIED 0

ISOLATIONLEVEL_CHAOS 0

ISOLATIONLEVEL_READUNCOMMITTED 0

ISOLATIONLEVEL_BROWSE 0

ISOLATIONLEVEL_CURSORSTABILITY 1

ISOLATIONLEVEL_READCOMMITTED 1

ISOLATIONLEVEL_REPEATABLEREAD 2

404

Page 419: Adaptive Server Anywhere

第 11 章 三层计算和分布式事务

从分布式事务恢复从分布式事务恢复从分布式事务恢复从分布式事务恢复

如果数据库服务器在未提交操作处于待执行状态时出现了故障,则它必须在启动时回退或者提交那些操作,以保持事务的原子特征。

如果恢复过程中发现有来自分布式事务的未提交操作,则数据库服务器会尝试连接到 DTC,并请求被重新征用到待执行或可疑事务中。重新

征用完成后, DTC 就会指导数据库服务器回退或提交该未完成的操

作。

如果重新征用过程失败, Adaptive Server Anywhere 就无法知道是应该

提交还是应该回退不确定的操作,因而恢复将失败。如果您希望这种状态的数据库进行恢复,而不考虑数据的不确定状态,可使用下列数据库服务器选项来强制恢复:

• -tmf 如果找不到 DTC,未完成的操作将回退,恢复继续。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > -tmf 服务器选项 "。

• -tmt 如果重新征用未能在指定的时间之前实现,未完成的操作

将回退,恢复继续。

有关更多信息,请参阅 "ASA 数据库管理指南 > 数据库服务器 > -tmt 服务器选项 "。

ISOLATIONLEVEL_SERIALIZABLE 3

ISOLATIONLEVEL_ISOLATED 3

DTC 隔离级别隔离级别隔离级别隔离级别Adaptive Server Anywhere 隔离级别隔离级别隔离级别隔离级别

405

Page 420: Adaptive Server Anywhere

在 EAServer 中使用 Adaptive Server Anywhere

在在在在 EAServer 中使用中使用中使用中使用 Adaptive Server Anywhere

本节将概述在 EAServer 3.0 或更高版本中使用 Adaptive Server Anywhere 时需要采取的操作。有关更多详细信息,请参阅 EAServer 文档。

配置配置配置配置 EAServer

在 Sybase EAServer 中安装的所有组件都共享同一事务处理协调器。

EAServer 3.0 以及更高版本提供了多个事务协调器供用户选择。您如果

要将 Adaptive Server Anywhere 包括在事务中,必须将 DTC 用作事务协

调器。本节说明如何相应地配置 EAServer 3.0 来将 DTC 用作事务协调

器。

EAServer 中的组件服务器名为 Jaguar。

❖ 配置配置配置配置 EAServer 以使用以使用以使用以使用 Microsoft DTC 事务模型:事务模型:事务模型:事务模型:

1 确保您的 Jaguar 服务器正在运行。

在 Windows 上, Jaguar 服务器通常是作为一个服务运行的。要

手工启动已安装的 Jaguar 服务器 (随 EAServer 3.0 提供),请

选择 " 开始 " → " 程序 " → "Sybase" → "EAServer" →"EAServer"。

2 启动 Jaguar Manager。

从 Windows 桌面上选择 " 开始 " → " 程序 " → "Sybase" →"EAServer" → "Jaguar Manager"。

3 从 Jaguar Manager 连接到 Jaguar 服务器。

从 Sybase Central 菜单,选择 " 工具 " → " 连接 " → "Jaguar Manager"。在连接对话框中,输入 jagadmin 作为 " 用户名 ",让

"口令"字段保持空白,输入 localhost 作为"主机名"。单击"确定"进行连接。

4 为 Jaguar 服务器设置事务模型。

406

Page 421: Adaptive Server Anywhere

第 11 章 三层计算和分布式事务

在左窗格中,打开 " 服务器 " 文件夹。在右窗格中,右击要配

置的服务器,从下拉菜单中选择 " 服务器属性 "。单击 " 事务 "选项卡,选择 "Microsoft DTC" 作为事务模型。单击 " 确定 " 完成操作。

设置组件事务属性设置组件事务属性设置组件事务属性设置组件事务属性

在 EAServer 中,您可以实现一个在多个数据库上执行操作的组件。您

可为此组件指派 " 事务属性事务属性事务属性事务属性 " 来定义它参与事务的方式。事务属性可具

有下列值:

• 不支持不支持不支持不支持 组件的方法永远不作为事务的一部分来执行。如果组件

是由另一个在事务中执行的组件激活的,则新实例的工作将在现有事务之外执行。这是缺省设置。

• 支持事务支持事务支持事务支持事务 组件可在事务的上下文中执行,但是在执行该组件的

方法时不需要连接。如果组件是直接由基础客户端实例化的,EAServer 不会开始事务。如果组件 A 是由组件 B 实例化的,而组

件 B 正在一个事务中执行,则组件 A 会在同一事务中执行。

• 需要事务需要事务需要事务需要事务 组件总是在事务中执行。当组件由基础客户端直接实

例化时,将开始新的事务。如果组件 A 是由组件 B 实例化的,而

组件 B 正在一个事务中执行,则组件 A 会在同一事务中执行;如

果组件 B 不是在事务中执行的,则组件 A 在一个新事务中执行。

• 需要新事务需要新事务需要新事务需要新事务 每当组件实例化时,都开始一个新的事务。如果组

件 A 是由组件 B 激活的,而组件 B 正在一个事务中执行,则组件 A 开始一个新的事务,新事务不受 B 的事务结果的影响;如果组

件 B 不是在事务中执行的,则组件 A 在一个新事务中执行。

例如,在 Sybase Virtual University 示例应用程序 (EAServer 中附带的 SVU 包)中, SVUEnrollment 组件的 enroll() 方法执行两种不同的操作

(在教程中预定座位,向学生收取教程费)。需要将这两种操作视为一个事务。

Microsoft Transaction Server 提供相同的属性值集。

407

Page 422: Adaptive Server Anywhere

在 EAServer 中使用 Adaptive Server Anywhere

❖ 设置组件的事务属性:设置组件的事务属性:设置组件的事务属性:设置组件的事务属性:

1 在 Jaguar Manager 中找到该组件。

为找到 Jaguar 示例应用程序中的 SVUEnrollment 组件,请连接

到 Jaguar 服务器,打开 " 程序包 " 文件夹,打开 SVU 程序包。

该程序包中的组件列于右侧窗格中。

2 为所需的组件设置事务属性。

右击该组件,从弹出菜单中选择 " 组件属性 "。单击 " 事务 " 选项卡,从列表中选择事务属性值。单击 " 确定 " 以完成操作。

SVUEnrollment 组件已经标上了 " 需要事务 " 标记。

设置了组件事务属性后,您就可以从该组件执行 Adaptive Server Anywhere 操作,并可确保事务在您指定的级别进行处理。

408

Page 423: Adaptive Server Anywhere

第 12 章

部署数据库和应用程序部署数据库和应用程序部署数据库和应用程序部署数据库和应用程序

关于本章关于本章关于本章关于本章 本章介绍了如何部署 Adaptive Server Anywhere 组件,确定部署所需的

文件并解决相关问题 (如连接设置)。

检查许可协议检查许可协议检查许可协议检查许可协议重新分发文件受到许可协议的制约。本文中的任何声明都不能替代许可协议中的任何内容。在考虑部署之前,请检查许可协议。

409

Page 424: Adaptive Server Anywhere

部署概述

部署概述部署概述部署概述部署概述

当您完成了数据库应用程序时,必须将应用程序 " 部署部署部署部署 " 到 终用户。

根据您的应用程序使用 Adaptive Server Anywhere 的方式 (作为嵌入式

数据库,以客户 / 服务器形式,等等),您可能必须将 Adaptive Server Anywhere 软件的组件与您的应用程序一起部署。您还可能必须部署配

置信息 (如数据源名称),以便使您的应用程序能够与 Adaptive Server Anywhere 进行通信。

检查许可协议检查许可协议检查许可协议检查许可协议重新分发文件受到 Sybase 许可协议的制约。本文中的任何声明都不能

替代许可协议中的任何内容。在考虑部署之前,请检查许可协议。

本章介绍下列部署步骤:

• 基于所选应用程序平台和体系结构确定必需的文件。

• 配置客户应用程序。

本章中的大部分介绍各个文件以及需要将它们放置的位置。但是,建议通过使用 Installshield 对象或使用静默安装来部署 Adaptive Server Anywhere 组件。有关信息,请参阅 "" 使用 InstallShield 对象和模板进行

部署 " 第 416 页 " 和 "" 使用静默安装来部署 " 第 418 页 "。

部署模型部署模型部署模型部署模型

部署所需的文件取决于所选部署模型。下面是一些可能的部署模型:

• 客户端部署客户端部署客户端部署客户端部署 您只能向 终用户部署 Adaptive Server Anywhere 的客户端部分,以便他们能够连接到集中放置的网络数据库服务器。

• 网络服务器部署网络服务器部署网络服务器部署网络服务器部署 您可以将网络服务器部署到多个办公室,然后

将客户端部署到这些办公室中的每个用户。

• 嵌入式数据库部署嵌入式数据库部署嵌入式数据库部署嵌入式数据库部署 您可以部署与个人数据库服务器一起运行的

应用程序。在这种情况下,需要在 终用户的计算机上同时安装客户端和个人服务器。

410

Page 425: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

• SQL Remote 部署部署部署部署 SQL Remote 应用程序的部署是对嵌入式数据

库部署模型的扩展。

• 数据库工具部署数据库工具部署数据库工具部署数据库工具部署 您可以部署 Interactive SQL、 Sybase Central 和其它管理工具。

文件的分发方式文件的分发方式文件的分发方式文件的分发方式

可通过两种方法来部署 Adaptive Server Anywhere:

• 使用使用使用使用 Adaptive Server Anywhere 安装安装安装安装 您可以让 终用户使用安

装程序。通过选择正确的选项,可保证每个 终用户获得他们所需的文件。

这种解决方案对很多部署情况都是 简单的。在这种情况下,您仍必须向 终用户提供一种连接到数据库服务器 (如 ODBC 数据

源)的方法。

有关更多信息,请参阅 "" 使用静默安装来部署 " 第 418 页 "。

• 开发自己的安装程序开发自己的安装程序开发自己的安装程序开发自己的安装程序 在许多情况下,您可能需要开发自己的,

包括 Adaptive Server Anywhere 文件的安装程序。这是一个更复杂

的选项,本章中的大部分是针对要开发自己的安装程序的用户的需要。

如果已为客户应用程序体系结构所需的服务器类型和操作系统安装了 Adaptive Server Anywhere,则可在 Adaptive Server Anywhere 安装目录中具有相应名称的子目录中找到必需的文件。

例如,假定选择了缺省安装目录,则安装目录的 win32 子目录中

会包括在 Windows 操作系统中运行服务器所必需的文件。

同样, InstallShield Professional 5.5 和更高版本的用户可以使用 SQL Anywhere Studio InstallShield 模板项目来部署他们自己的应用

程序。使用这项功能,您可以使用整个模板项目或只是安装所需的部分来快速建立应用程序的安装文件。

无论选择哪个选项,都不得违反许可协议中的条款。

411

Page 426: Adaptive Server Anywhere

了解安装目录和文件名

了解安装目录和文件名了解安装目录和文件名了解安装目录和文件名了解安装目录和文件名

为了使部署的应用程序正确工作,数据库服务器和 Client Library 都必须

能够找到它们所需的文件。部署文件之间的相对位置应当与 Adaptive Server Anywhere 安装的方式相同。

实际上,这意味着 PC 上的大多数文件都属于同一目录。例如,在 Windows 上,客户端和数据库服务器所需的文件都安装在同一目录中,

即 Adaptive Server Anywhere 安装目录的 win32 子目录。

有关该软件在何处查找文件的完整说明,请参阅 "ASA 数据库管理指南 > 文件位置和安装设置 > Adaptive Server Anywhere 如何定位文件 "。

UNIX 部署问题部署问题部署问题部署问题

UNIX 部署在下列方面不同于 PC 部署:

• 目录结构目录结构目录结构目录结构 对于 UNIX 安装,目录结构如下:

在 AIX 上,缺省的根目录是 /usr/lpp/sybase/SYBSsa8 而非 /opt/sybase/SYBSsa8。

• 文件扩展名文件扩展名文件扩展名文件扩展名 在本章中的表中,列出的共享对象带有扩展名 .so。对于 HP-UX,扩展名是 .sl。

在 AIX 操作系统上,应用程序需要链接的共享对象会带有扩展名 .a。

• 符号链接符号链接符号链接符号链接 每个共享对象都被安装为具有附加扩展名 .1(一)的

同名文件的符号链接。例如, libdblib8.so 是同一目录中 libdblib8.so.1 文件的符号链接。

目录目录目录目录 内容内容内容内容

/opt/sybase/SYBSsa8/bin 可执行文件

/opt/sybase/SYBSsa8/lib 共享对象和库

/opt/sybase/SYBSsa8/res 字符串文件

412

Page 427: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

如果 Adaptive Server Anywhere 安装需要补丁程序,它们将附加以

扩展名 .2,且必须重定向符号链接。

• 线程和非线程应用程序线程和非线程应用程序线程和非线程应用程序线程和非线程应用程序 大多数共享对象都以两种形式提供,一

种是在文件扩展名前有附加字符 _r。例如,除了 libdblib8.so,还有一个名为 libdblib8_r.so 的文件。在这种情况下,线程应

用程序必须链接到带有 _r 的共享对象,而非线程应用程序必须链

接到不带 _r 字符的共享对象。

• 字符集转换字符集转换字符集转换字符集转换 如果您要使用数据库服务器字符集转换 ( -ct 服务器

选项),则需要包括下列文件:

• libunic.so

• charsets/ directory subtree

• asa.cvf

有关该软件在何处查找文件的说明,请参阅 "ASA 数据库管理指南 > 文件位置和安装设置 > Adaptive Server Anywhere 如何定位文件 "。

文件命名约定文件命名约定文件命名约定文件命名约定

Adaptive Server Anywhere 使用一致的文件命名约定来帮助标识系统组件

和分组。

这些约定包括:

• 版本号版本号版本号版本号 Adaptive Server Anywhere 的版本号由主要的服务器组件

的文件名来表示 (.exe 和 .dll 文件)。

例如,文件 dbeng8.exe 是 8.0 版的可执行文件。

• 语言语言语言语言 语言资源库中使用的语言由它的文件名中的双字母代码表

示。版本号前面的两个字符表示该库中使用的语言。例如,dblgen8.dll 是英语的语言资源库。这些双字母代码由 ISO 标准 639 指定。

有关语言标签的更多信息,请参阅 "ASA 数据库管理指南 > 国际

语言和字符集 > 了解地区语言 "。

413

Page 428: Adaptive Server Anywhere

了解安装目录和文件名

您可以从 Sybase Web 站点免费下载包含语言资源部署 DLL 的 " 国际资

源部署工具包 "。

❖ 从从从从 Sybase Web 站点下载站点下载站点下载站点下载 " 国际资源部署工具包国际资源部署工具包国际资源部署工具包国际资源部署工具包 "::::

1 在 Web 浏览器中打开以下 URL:

http://www.sybase.com/products/anywhere/

2 在该页左侧的 "SQL Anywhere Studio" 标题下,单击

"Downloads" (下载)。

3 在 "Emergency Bug Fix/Updates" (紧急错误修正 / 更新)标题

下,单击 Emergency Bug Fixes and Updates for iAnywhere m-Business Studio。

4 登录到您的 Sybase Web 帐号。

如果您还没有 Sybase Web 帐号,可单击 "Create a New Account"(新建帐号)来创建。

5 从可用下载的列表中,选择与当前使用的 Adaptive Server Anywhere 的平台和版本相匹配的 International Resources Deployment Kit。

有关 Adaptive Server Anywhere 中可用语言的列表,请参阅 "ASA 数据

库管理指南 > 国际语言和字符集 > 提供的归类 "。

标识其它文件类型标识其它文件类型标识其它文件类型标识其它文件类型 下表按照 Adaptive Server Anywhere 文件的文件扩展名来标识它们的平

台和功能。 Adaptive Server Anywhere 尽可能遵循标准的文件扩展名约

定。

文件扩展名文件扩展名文件扩展名文件扩展名 平台平台平台平台 文件类型文件类型文件类型文件类型

.nlm Novell NetWare NetWare 可装载模块

.cnt、 .ftg、

.fts、 .gid、

.hlp、 .chm、 .chw

Windows 帮助系统文件

414

Page 429: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

数据库文件名数据库文件名数据库文件名数据库文件名 Adaptive Server Anywhere 数据库由下列元素组成:

• 数据库文件数据库文件数据库文件数据库文件 该文件用于存储有组织格式的信息。该文件使用 .db 文件扩展名。

• 事务日志文件事务日志文件事务日志文件事务日志文件 该文件用于记录对存储在数据库文件中的数据进

行的所有更改。该文件使用 .log 文件扩展名,如果该文件不存在

并且指定了要使用日志文件,就会由 Adaptive Server Anywhere 生成该文件。镜像事务日志的缺省扩展名为 .mlg。

• 写文件写文件写文件写文件 如果您的应用程序使用写文件,它的文件扩展名通常为 .wrt。

• 压缩数据库文件压缩数据库文件压缩数据库文件压缩数据库文件 如果您提供只读的压缩数据库文件,则它的扩

展名通常为 .cdb。

上述文件由 Adaptive Server Anywhere 关系数据库管理系统更新、维护

和管理。

.lib 因开发工具而异 用于创建嵌入式 SQL 可执行文件的静态运行时库

.cfg、 .cpr、

.dat、 .loc、

.spr、 .srt、 .xlt

Windows Sybase Adaptive Server Enterprise 组件

.cmd .bat Windows 命令文件

.res NetWare、 UNIX 面向非 Windows 环境

的语言资源文件

.dll Windows 动态链接库

.so .sl .a UNIX 共享对象 (Sun Solaris 和 IBM AIX)或共享库 (HP-UX) 文件。相当于 PC 平台上的 DLL。

文件扩展名文件扩展名文件扩展名文件扩展名 平台平台平台平台 文件类型文件类型文件类型文件类型

415

Page 430: Adaptive Server Anywhere

使用 InstallShield 对象和模板进行部署

使用使用使用使用 InstallShield 对象和模板进行部署对象和模板进行部署对象和模板进行部署对象和模板进行部署

如果您使用的是 InstallShield 6 和更高版本,则可以在安装程序中包括 SQL Anywhere Studio InstallShield 对象。用于部署客户端、个人数据库

服务器、网络服务器和管理工具的对象位于 SQL Anywhere 目录下的 deployment\Object 目录中。

InstallShield Professional 5.5 和更高版本的用户可使用 SQL Anywhere Studio InstallShield 模板项目来降低部署工作量。用于部署网络服务器、

个人服务器、客户端界面和管理工具的模板位于 SQL Anywhere 8\deployment\Templates 文件夹中。

如果您拥有 InstallShield 6 或更高版本,则建议使用 InstallShield 对象而

不使用模板,因为它们更便于与其它组件一起合并到安装中。

❖ 将模板项目添加到将模板项目添加到将模板项目添加到将模板项目添加到 InstallShield IDE 中:中:中:中:

1 启动 InstallShield IDE。

2 选择 " 文件 " → " 打开 "。

3 改变目录到 SQL Anywhere 8 安装目录和部署文件夹。

例如,改变目录到

C:\Program Files\Sybase\SQL Anywhere 8\deployment

4 打开与要部署的对象类型相对应的模板文件夹。

您可以选择 NetworkServer、 PersonalServer、 Client 或 JavaTools。

5 选择具有 .ipr 扩展名的文件。

在 InstallShield IDE 中打开该项目。 " 项目 " 窗格显示该模板的

图标。

这些模板将在安装时被修改以便列在所有 .fgl 文件中的各个

文件的路径指向实际安装的 ASA。只需在 InstallShield IDE 中装载模板并构建介质,即可立即运行模板。

416

Page 431: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

注意:注意:注意:注意: 在建立介质时,将看到有关空文件组的警告。这些警告是由空文件组造成的,这些空文件组作为应用程序文件的占位符添加到模板中。要删除这些警告,您可以将应用程序的文件添加到文件组中,也可以删除或重命名文件组。

417

Page 432: Adaptive Server Anywhere

使用静默安装来部署

使用静默安装来部署使用静默安装来部署使用静默安装来部署使用静默安装来部署

运行静默安装时无需用户输入且不向用户指示安装正在进行。在 Windows 操作系统上,您可以按照 Adaptive Server Anywhere 静默安装

的方式,从自己的安装程序中调用 Adaptive Server Anywhere InstallShield 安装程序。静默安装还用于 Microsoft 的 Systems Management Server (请参阅 ""SMS 安装 " 第 421 页 ")。

您可以将静默安装用于 "" 部署模型 " 第 410 页 " 中介绍的任何部署模

型,还可以使用静默安装来部署 MobiLink 同步服务器。

创建静默安装创建静默安装创建静默安装创建静默安装

静默安装使用的安装选项是从 " 响应文件响应文件响应文件响应文件 " 获取的。响应文件是通过使

用 -r 选项运行 Adaptive Server Anywhere 的 setup 程序来创建的。静默

安装是通过使用 -s 选项运行 setup 来执行的。

不要使用浏览按钮不要使用浏览按钮不要使用浏览按钮不要使用浏览按钮在创建静默安装时不要使用浏览按钮。浏览按钮的记录不可靠。

❖ 创建静默安装:创建静默安装:创建静默安装:创建静默安装:

1 (可选)删除已安装的任何 Adaptive Server Anywhere。

2 打开系统的命令提示符,更改到包含安装映像的目录 (包括 setup.exe、 setup.ins 等)。

3 使用 " 记录 " 模式安装该软件。

键入以下命令:

setup -r

该命令运行 Adaptive Server Anywhere 安装程序并根据您的选项

创建响应文件。该响应文件名为 setup.iss,它位于 Windows 目录中。该文件包含您在安装过程中针对对话框作出的响应。

418

Page 433: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

当您在记录模式下运行时,即使需要重新启动操作系统,安装程序也不提供重启。

4 安装 Adaptive Server Anywhere,使用与在 终用户机器上部署

应用程序和 Adaptive Server Anywhere 时一样的选项和设置。在

静默安装过程中,您可以覆盖这些路径。

运行静默安装运行静默安装运行静默安装运行静默安装

您自己的安装程序必须使用 -s 选项调用 Adaptive Server Anywhere 静默

安装。本节介绍了如何使用静默安装。

❖ 使用静默安装:使用静默安装:使用静默安装:使用静默安装:

1 将用于激活 Adaptive Server Anywhere 静默安装的命令添加到安

装过程中。

如果安装映像目录中有响应文件,则可以通过从包含安装映像的目录中输入下列命令来运行静默安装:

setup -s

如果响应文件位于其它位置,则必须使用 -f1 选项指定响应文件

的位置。在以下命令行中, f1 和引号之间不得有任何空格。

setup -s -f1"c:\winnt\setup.iss"

要从另一个 InstallShield 脚本激活安装,则可以使用以下命令:

DoInstall( "ASA_install_image_path\SETUP.INS","-s", WAIT );

您可以使用选项来覆盖所选择的 Adaptive Server Anywhere 目录

和共享目录的路径:

setup TARGET_DIR=dirname SHARED_DIR=shared_dir -s

TARGET_DIR 和 SHARED_DIR 参数必须位于所有其它选项的

前面。

2 检查目标计算机是否需要重新启动。

419

Page 434: Adaptive Server Anywhere

使用静默安装来部署

安装程序在目标目录中创建一个名为 silent.log 的文件。该

文件包含单一一个名为 ResponseResult 的部分,该部分包含以

下行:

Reboot=value

此行指示目标计算机是否需要重新启动以完成安装,并且它的值为 0 或 1,其含义如下:

• Reboot=0 无需重新启动。

• Reboot=1 BATCH_INSTALL 标志是在安装过程中设置

的,目标计算机需要重新启动。调用静默安装的安装程序负责检查 Reboot 条目以及根据需要重新启动目标计算机。

3 验证安装程序已正确完成。

安装程序在包含响应文件的目录中创建名为 setup.log 的文

件。日志文件包含有关静默安装的报告。该文件的 后部分名为 ResponseResult,其中包含以下行:

ResultCode=value

此行指示安装是否成功。 ResultCode 为非零指示在安装过程中

出现了错误。有关错误代码的说明,请参阅"InstallShield 文档 "。

420

Page 435: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

SMS 安装安装安装安装

Microsoft System Management Server (SMS) 需要不重新启动目标计算机

的静默安装。 Adaptive Server Anywhere 静默安装不重新启动计算机。

SMS 分发包应当包含响应文件、安装映像和 asa8.pdf 包定义文件

(在 Adaptive Server Anywhere CD ROM 上的 \extras 文件夹中提供)。

该 PDF 文件中安装程序的命令包含下列选项:

• -s 选项用于静默安装

• -SMS 选项指示它正被 SMS 激活。

• -m 选项用于生成 MIF 文件。 SMS 使用 MIF 文件来确定安装是否

成功。

421

Page 436: Adaptive Server Anywhere

部署客户端应用程序

部署客户端应用程序部署客户端应用程序部署客户端应用程序部署客户端应用程序

为了部署针对网络数据库服务器运行的客户应用程序,您必须向 终用户提供下列项目:

• 客户应用程序客户应用程序客户应用程序客户应用程序 应用程序软件本身与数据库软件无关,因此在此

不予介绍。

• 数据库接口文件数据库接口文件数据库接口文件数据库接口文件 客户应用程序需要它所使用的数据库接口文件

(ODBC、 JDBC、嵌入式 SQL 或 Open Client)。

• 连接信息连接信息连接信息连接信息 每个客户应用程序都需要数据库连接信息。

所需的接口文件和连接信息因应用程序正在使用的接口而异。下列各节分别介绍了每个接口。

部署客户端 简单的方法就是使用提供的 InstallShield 对象。有关更多

信息,请参阅 "" 使用 InstallShield 对象和模板进行部署 " 第 416 页 "。

部署部署部署部署 OLE DB 和和和和 ADO 客户端客户端客户端客户端

部署 OLE DB Client Library 的 简单方法就是使用 InstallShield 对象或

模板。有关信息,请参阅 "" 使用 InstallShield 对象和模板进行部署 " 第416 页 "。如果您希望创建自己的安装,本节介绍了用于部署到 终用

户的文件。

每个 OLE DB 客户机都必须具有下列项目:

• 可工作的可工作的可工作的可工作的 OLE DB 安装安装安装安装 Microsoft Corporation 提供了可重新分发

的 OLE DB 文件以及重新分发指导。此处不再详细介绍。

• Adaptive Server Anywhere OLE DB 提供程序提供程序提供程序提供程序 下表显示运行 Adaptive Server Anywhere OLE DB 提供程序所需的文件。这些文

件应放在单一目录中。 Adaptive Server Anywhere 安装程序将它们

全部放在 SQL Anywhere 安装目录的操作系统子目录 (例如:

win32)中。

422

Page 437: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

OLE DB 提供程序需要许多注册表项。您可以通过使用 Windows 上的 regsvr32 实用程序或 Windows CE 上的 regsvrce 自行注册 DLL 来创

建这些项。

有关更多信息,请参阅 "ASA 数据库管理指南 > 国际语言和字符集 > 为 Windows CE 创建数据库 "和 ""在 Windows CE 上链接 ODBC 应用程序 " 第 279 页 "。

部署部署部署部署 ODBC 客户端客户端客户端客户端

部署 ODBC 客户端 简单的方法就是使用 InstallShield 对象或模板。有

关信息,请参阅 "" 使用 InstallShield 对象和模板进行部署 " 第 416 页 "。

每个 ODBC 客户机都必须具有下列项目:

• 可工作的可工作的可工作的可工作的 OLE DB 安装安装安装安装 Microsoft Corporation 提供了可重新分发

的 OLE DB 文件以及重新分发指导。此处不再详细介绍。

Microsoft 为 Windows 操作系统提供它们的 ODBC 驱动程序管理

器。SQL Anywhere Studio 包括用于 UNIX 的 ODBC 驱动程序管理

器。没有用于 Windows CE 的 ODBC 驱动程序管理器。

ODBC 应用程序可在无驱动程序管理器的情况下运行。在拥有 ODBC 驱动程序管理器的平台上,不建议这样做。

说明说明说明说明 Windows Windows CE

OLE DB 驱动程序文件 dboledb8.dll dboledb8.dll

OLE DB 驱动程序文件 dboledba8.dll dboledba8.dll

语言资源库 dblgen8.dll dblgen8.dll

" 连接 " 对话框 dbcon8.dll 无

423

Page 438: Adaptive Server Anywhere

部署客户端应用程序

根据需要更新根据需要更新根据需要更新根据需要更新 ODBCSQL Anywhere 安装程序会更新 "Microsoft 数据访问组件 " (包括 ODBC)旧有的安装。如果您要部署自己的应用程序,则必须确

保 ODBC 安装能够满足您的应用程序的需要。

• Adaptive Server Anywhere ODBC 驱动程序驱动程序驱动程序驱动程序 这是指 dbodbc8.dll 文件以及一些其它文件。

有关更多信息,请参阅 ""ODBC 驱动程序所需的文件 " 第 424 页

"。

• 连接信息连接信息连接信息连接信息 客户应用程序必须能够访问连接到服务器所需的信息。

该信息通常包括在 ODBC 数据源中。

ODBC 驱动程序所需的文件驱动程序所需的文件驱动程序所需的文件驱动程序所需的文件

下表显示运行 Adaptive Server Anywhere ODBC 驱动程序所需的文件。

这些文件应放在单一目录中。 Adaptive Server Anywhere 安装将它们全

部放在 SQL Anywhere 安装目录的操作系统子目录 (例如:

win32)中。

注意注意注意注意 • 您的 终用户必须有正常工作的 ODBC 安装,其中包括驱动程序

管理器。 Microsoft ODBC SDK 中提供了部署 ODBC 的指导。

• 在以下情况下需要 "连接 "对话框: 终用户要创建各自的数据源,

他们需要在连接到数据库中时输入用户 ID 和口令,或者他们需要

为了任何其它目的而显示 " 连接 " 对话框。

说明说明说明说明 Windows Windows CE UNIX

ODBC 驱动程序 dbodbc8.dll dbodbc8.dll libdbodbc8.so libdbtasks8.so

语言资源库 dblgen8.dll dblgen8.dll dblgen8.res

" 连接 " 对话框 dbcon8.dll 无 无

424

Page 439: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

• 只有当应用程序依赖 OEM 到 ANSI 字符集转换时才需要 ODBC 转换器。

有关更多信息,请参阅 "ASA 数据库管理指南 > 国际语言和字符

集 > 为 Windows CE 创建数据库 " 和 "" 在 Windows CE 上链接 ODBC 应用程序 " 第 279 页 "。

• 对于 UNIX 上的多线程应用程序,请使用 libdbodbc8_r.so 和 libdbtasks8_r.so。

配置配置配置配置 ODBC 驱动程序驱动程序驱动程序驱动程序

除了将 ODBC 驱动程序文件复制到磁盘上以外,您的安装程序还必须

创建一组注册表项以便正确安装 ODBC 驱动程序。

Windows Adaptive Server Anywhere 安装程序对注册表进行更改以标识和配置 ODBC 驱动程序。如果您正为 终用户创建安装程序,则应当配置相同

的设置。

您可以使用 regedit 实用程序来检查注册表项。

Adaptive Server Anywhere ODBC 驱动程序由以下注册键中的一组注册表

值向系统标识:

HKEY_LOCAL_MACHINE\SOFTWARE\

ODBC\ODBCINST.INI\

Adaptive Server Anywhere 8.0

这些值如下:

在以下键中也有一个注册表值:

值的名称值的名称值的名称值的名称 值的类型值的类型值的类型值的类型 值的数据值的数据值的数据值的数据

Driver 字符串 path\dbodbc8.dll

Setup 字符串 path\dbodbc8.dll

425

Page 440: Adaptive Server Anywhere

部署客户端应用程序

HKEY_LOCAL_MACHINE\SOFTWARE\

ODBC\ODBCINST.INI\

ODBC Drivers

这些值如下:

第三方第三方第三方第三方 ODBC 驱动驱动驱动驱动

程序程序程序程序

如果您在非 Windows 操作系统上使用第三方 ODBC 驱动程序,请查阅

该驱动程序的文档以了解如何配置 ODBC 驱动程序。

部署连接信息部署连接信息部署连接信息部署连接信息

ODBC 客户连接信息通常以 ODBC 数据源形式部署。您可以按照下列

方式之一来部署 ODBC 数据源:

• 编程方式编程方式编程方式编程方式 将数据源的说明添加到 终用户的注册表或 ODBC 初始化文件中。

• 手工手工手工手工 向 终用户提供指导,以便他们能够在自己的机器上创建

相应的数据源。

从 " 用户 DSN" 选项卡或 " 系统 DSN" 选项卡,使用 ODBC 管理

器手工创建数据源。 Adaptive Server Anywhere ODBC 驱动程序显

示用于输入设置的配置对话框。数据源设置包括数据库文件的位置、数据库服务器的名称以及任何启动参数和其它选项。

对于每种方式,本节都向您提供需要了解的信息。

数据源类型数据源类型数据源类型数据源类型 有三种数据源:用户数据源、系统数据源和文件数据源。

用户数据源定义存储在注册表的某个部分中,其中包含了当前登录到系统的特定用户的设置。但是,系统数据源对于所有用户和 Windows 服务可用,无论用户是否登录到系统, Windows 服务都运行。给定一个

名为 MyApp 的正确配置的系统数据源,任何用户都可以通过在 ODBC 连接字符串中提供 DSN=MyApp 来使用该 ODBC 连接。

值的名称值的名称值的名称值的名称 值的类型值的类型值的类型值的类型 值的数据值的数据值的数据值的数据

Adaptive Server Anywhere 8.0 字符串 Installed

426

Page 441: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

文件数据源不保留在注册表中,但是保留在一个专门的目录中。连接字符串必须提供 FileDSN 连接参数才能使用文件数据源。

数据源注册表项数据源注册表项数据源注册表项数据源注册表项 每个用户数据源都由注册表项向系统标识。

您必须在特定的注册表键中输入一组注册表值。对于用户数据源,该键如下:

HKEY_CURRENT_USER\SOFTWARE\

ODBC\ODBC.INI\

userdatasourcename

对于系统数据源,该键如下:

HKEY_LOCAL_MACHINE\SOFTWARE\

ODBC\ODBC.INI\

systemdatasourcename

该键包含一组注册表值,每个值都与一个连接参数相对应。例如,与 ASA 8.0 Sample 数据源相对应的 ASA 8.0 Sample 键包含下列设置:

在这些条目中,路径 是指 Adaptive Server Anywhere 安装目录。

另外,您必须将数据源添加到注册表中的数据源列表中。对于用户数据源,使用以下注册表键:

值的名称值的名称值的名称值的名称 值的类型值的类型值的类型值的类型 值的数据值的数据值的数据值的数据

Autostop 字符串 Y

DatabaseFile 字符串 路径 \asademo.db

Description 字符串 Adaptive Server Anywhere Sample Database

Driver 字符串 路径 \win32\dbodbc8.dll

PWD 字符串 sql

Start 字符串 路径 \win32\dbeng8.exe -c 8m

UID 字符串 dba

427

Page 442: Adaptive Server Anywhere

部署客户端应用程序

HKEY_CURRENT_USER\SOFTWARE\

ODBC\ODBC.INI\

ODBC Data Sources

对于系统数据源,使用以下注册表键:

HKEY_LOCAL_MACHINE\SOFTWARE\

ODBC\ODBC.INI\

ODBC Data Sources.

该值将每个数据源与一个 ODBC 驱动程序相关联。值的名称是数据源

的名称,值的数据是 ODBC 驱动程序的名称。例如,由 Adaptive Server Anywhere 安装的用户数据源名为 ASA 8.0 Sample,它的值如下:

注意:注意:注意:注意:ODBC 设置很容易被看到设置很容易被看到设置很容易被看到设置很容易被看到

用户数据源配置可能包含敏感的数据库设置 (如用户的 ID 和口令)。

这些设置以纯文本形式存储在注册表中,可通过使用由 Microsoft 随操

作系统提供的 Windows 注册表编辑器 regedit.exe 或 regedt32.exe 来查看。您可以选择加密口令或要求用户在连接时输入口令。

必需的和可选的连接必需的和可选的连接必需的和可选的连接必需的和可选的连接参数参数参数参数

您可以按照以下方式来在 ODBC 配置字符串中标识数据源名称:

DSN=userdatasourcename

如果在连接字符串中提供 DSN 参数,则在注册表中先搜索当前用户数

据源定义,然后搜索系统数据源。只有在 ODBC 连接字符串中提供了 FileDSN 时才搜索文件数据源。

下表阐释了当数据源存在且以 DSN 或 FileDSN 参数形式包括在应用程

序的连接字符串中时,用户和开发人员在这种情况下应该注意的一些问题。

值的名称值的名称值的名称值的名称 值的类型值的类型值的类型值的类型 Value data

ASA 8.0 Sample 字符串 Adaptive Server Anywhere 8.0

428

Page 443: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

有关 ODBC 连接和配置的更多信息,请参阅下列内容:

• "ASA 数据库管理指南 > 连接到数据库 "。

• 开放式数据库连接 (ODBC) SDK (可从 Microsoft 获得)。

部署嵌入式部署嵌入式部署嵌入式部署嵌入式 SQL 客户端客户端客户端客户端

部署嵌入式 SQL 客户端 简单的方法就是使用 InstallShield 对象或模

板。有关信息,请参阅 "" 使用 InstallShield 对象和模板进行部署 " 第416 页 "。

部署嵌入式 SQL 客户端涉及到下列内容:

• 安装文件安装文件安装文件安装文件 每台客户机都必须拥有 Adaptive Server Anywhere 嵌入

式 SQL 客户应用程序所需的文件。

当数据源当数据源当数据源当数据源 … 连接字符串还必须标识连接字符串还必须标识连接字符串还必须标识连接字符串还必须标识… 用户必须提供用户必须提供用户必须提供用户必须提供 …

包含 ODBC 驱动程序

的名称和位置;数据库文件 / 服务器的名称;

启动参数;用户 ID 和口令。

无额外信息 无额外信息。

只包含 ODBC 驱动程

序的名称和位置。

数据库文件 / 服务器的名

称;(可选)用户 ID 和口令。

用户 ID 和口令 (如

果未在 DSN 或 ODBC 连接字符串中提供)。

不存在 要使用的 ODBC 驱动程

序的名称,采用以下格式:

Driver={ODBCdrivername}

以及数据库、数据库文件或数据库服务器的名称;(可选)其它连接参数(如用户 ID 和口

令)。

用户 ID 和口令 (如

果未在 ODBC 连接字

符串中提供)。

429

Page 444: Adaptive Server Anywhere

部署客户端应用程序

• 连接信息连接信息连接信息连接信息 客户应用程序必须能够访问连接到服务器所需的信息。

该信息可包括在 ODBC 数据源中。

为嵌入式为嵌入式为嵌入式为嵌入式 SQL 客户端安装文件客户端安装文件客户端安装文件客户端安装文件

下表显示嵌入式 SQL 客户端所需的文件。

注意

• 如果客户端只是和个人数据库服务器一起运行,则无需网络端口 DLL。

• 如果客户应用程序使用 ODBC 数据源来保存连接参数,则 终用

户必须有正常运行的 ODBC 安装。用于部署 ODBC 的指导包括在 Microsoft ODBC SDK 中。

有关部署 ODBC 信息的更多信息,请参阅 "" 部署 ODBC 客户端 " 第 423 页 "。

• 在以下情况下需要 " 连接 " 对话框: 终用户将要创建各自的数据

源;他们需要在连接到数据库中时输入用户 ID 和口令;或者他们

需要为了任何其它目的而显示 " 连接 " 对话框。

• 对于 UNIX 上的多线程应用程序,请使用 libdblib8_r.so 和 libdbtasks8_r.so。

说明说明说明说明 Windows UNIX

接口库 dblib8.dll libdblib8.so, libdbtasks8.so

语言资源库 dblgen8.dll dblgen8.res

IPX 网络通信 dbipx8.dll 无

" 连接 " 对话框 dbcon8.dll 无

430

Page 445: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

连接信息连接信息连接信息连接信息

您可以按照下列某种方式来部署嵌入式 SQL 连接信息:

• 手工手工手工手工 向 终用户提供关于在他们的计算机上创建相应数据源的

指导。

• 文件文件文件文件 以应用程序可以读取的格式分发包含连接信息的文件。

• ODBC 数据源数据源数据源数据源 您可以使用 ODBC 数据源保存连接信息。这种情

况下,您需要可重新分发的 ODBC 文件的子集 (可从 Microsoft 获得)。有关详细信息,请参阅 "" 部署 ODBC 客户端 " 第 423 页

"。

• 硬编码硬编码硬编码硬编码 您可以将连接信息硬编码到应用程序中。这是一种不太

灵活的方法,可能会有一定限制,如在升级数据库时。

部署部署部署部署 JDBC 客户端客户端客户端客户端

除 Java 运行时环境以外,每个 JDBC 客户端都需要 Sybase jConnect JDBC 驱动程序或 JDBC-ODBC Bridge。

要部署 JDBC-ODBC Bridge,您必须部署下列文件:

• jodbc.jar 该文件应在应用程序的类路径中。

• dbjodbc8.dll 该文件应在系统路径中。在 UNIX 或 Linux 环境

中,该文件是共享库 (dbjodbc8.so)。

• The ODBC 驱动程序文件。有关更多信息,请参阅 ""ODBC 驱动程

序所需的文件 " 第 424 页 "。

为了连接到数据库,您的 Java 应用程序需要一个 URL。该 URL 指定驱

动程序、要使用的机器以及数据库服务器所监听的端口。

有关 URL 的更多信息,请参阅 "" 提供服务器的 URL" 第 148 页 "。

431

Page 446: Adaptive Server Anywhere

部署客户端应用程序

部署部署部署部署 Open Client 应用程序应用程序应用程序应用程序

为了部署 Open Client 应用程序,每台客户机都需要 Sybase Open Client 产品。您必须从 Sybase 单独购买 Open Client 软件。它包含自己的安装

指导。

Open Client 客户端的连接信息保存在接口文件中。有关接口文件的信

息,请参阅 "Open Client 文档 " 和 "ASA 数据库管理指南 > 将 Adaptive Server Anywhere 用作 Open Server > 配置 Open Server"。

432

Page 447: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

部署管理工具部署管理工具部署管理工具部署管理工具

在许可协议的范围内,您可以部署一组管理工具,包括 Interactive SQL、 Sybase Central 和 dbconsole 监控实用程序。

部署管理工具 简单的方法就是使用提供的 InstallShield 对象。有关更

多信息,请参阅 "" 使用 InstallShield 对象和模板进行部署 " 第 416 页 "。

部署部署部署部署 Interactive SQL

如果运行客户应用程序的计算机上资源有限,您可能需要部署 C 版本的 Interactive SQL (dbisqlc.exe) 而非标准版本 (dbisql.exe 和它的相

关 Java 类)。

dbisqlc 可执行文件需要标准的嵌入式 SQL 客户端库。

有关管理工具系统要求的信息,请参阅 "SQL Anywhere Studio 介绍 > 教程:使用 InfoMaker 创建报告 > 管理工具系统要求 "。

433

Page 448: Adaptive Server Anywhere

部署数据库服务器

部署数据库服务器部署数据库服务器部署数据库服务器部署数据库服务器

您可以通过让 终用户使用 SQL Anywhere Studio 安装程序来部署数据

库服务器。通过选择正确的选项,保证每个 终用户获得他们所需的文件。

部署个人数据库服务器或网络数据库服务器 简单的方法就是使用提供的 InstallShield 对象。有关更多信息,请参阅 "" 使用 InstallShield 对象

和模板进行部署 " 第 416 页 "。

为了运行数据库服务器,您需要安装一组文件。下表列出了这些文件。这些文件的所有重新分发由许可协议的条款控制。重新分发数据库服务器文件之前,您必须确认自己是否有进行此操作的权限。

Windows UNIX NetWare

dbeng8.exe dbeng8 无

dbsrv8.exe dbsrv8 dbsrv8.nlm

dbserv8.dll libdbserv8.so、 libdbtasks8_r.so

dblgen8.dll dblgen8.res dblgen8.res

dbjava8.dll (1) libdbjava8.so (1) dbjava8.nlm (1)

dbctrs8.dll 无 无

dbextf.dll (2) libdbextf.so (2) dbextf.nlm (2)

asajdbc.zip (1,3) asajdbc.zip (1,3) asajdbc.zip (1,3)

asajrt12.zip (1,3) asajrt12.zip (1,3) asajrt12.zip (1,3)

classes.zip (1,3) classes.zip (1,3) classes.zip (1,3)

dbmem.vxd (4) 无 无

libunic.dll libunic.so 无

asa.cvf asa.cvf asa.cvf

charsets\ directory

charsets/ directory

434

Page 449: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

1. 只有在数据库中使用 Java 时才需要。对于使用 JDK 1.1 初始化的数据

库,分发 asajdbc.zip。对于使用 JDK 1.2 或 JDK 1.3 初始化的数据库,

分发 asajrt13.zip。

2. 只有当使用系统扩展的存储过程和函数 (xp_) 时才需要。

3. 安装以便 CLASSPATH 环境变量能够在该文件中找到类。

4. 在 Windows 95/98/Me 上使用动态高速缓存调整时需要。

注意注意注意注意 • 您应当根据自己的情况选择是部署个人数据库服务器 (dbeng8) 还是网络数据库服务器 (dbsrv8)。

• 只有当数据库服务器要在数据库功能中使用 Java 时才需要 Java DLL (dbjava8.dll)。

• 该表不包括运行实用程序 (如 dbbackup)所需的文件。

有关部署实用程序的信息,请参阅 "" 部署管理工具 " 第 433 页 "。

• zip 文件只有对于在数据库中使用 Java 的应用程序来说才是必需

的,并且必须安装到用户的 CLASSPATH 环境变量指定的位置。

部署数据库部署数据库部署数据库部署数据库

通过将数据库文件安装到 终用户的磁盘上来部署数据库文件。

只要数据库服务器完全关闭,您就无需用数据库文件部署事务日志文件。当 终用户开始运行数据库时,就创建一个新事务日志。

对于 SQL Remote 应用程序,数据库必须在正确同步的状态下创建,在

这种情况下无需事务日志。您可以使用 Extraction 实用程序实现该目

的。

在只读介质上部署数据库在只读介质上部署数据库在只读介质上部署数据库在只读介质上部署数据库

只要您在只读模式下运行数据库或者使用写文件,就可以在只读介质(如 CD-ROM)上分发数据库。

435

Page 450: Adaptive Server Anywhere

部署数据库服务器

有关在只读模式下运行数据库的更多信息,请参阅 "ASA 数据库管理指

南 > 数据库服务器 > -r 服务器选项 "。

为了能够更改用只读介质 (例如 CD-ROM)分发的 Adaptive Server Anywhere 数据库,您可以使用 " 写文件写文件写文件写文件 "。写文件记录对只读数据库文

件进行的更改,它位于读 / 写存储介质 (例如硬盘)上。

在这种情况下,数据库文件位于 CD-ROM 上,而写文件位于磁盘上。

连接建立在写文件上,以便在磁盘上维护事务日志文件。

有关写文件的更多信息,请参阅 "ASA 数据库管理指南 > 使用数据库文

件 > 使用写文件 "。

436

Page 451: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

部署嵌入式数据库应用程序部署嵌入式数据库应用程序部署嵌入式数据库应用程序部署嵌入式数据库应用程序

本节提供有关部署嵌入式数据库应用程序的信息,在这种情况下,应用程序和数据库都驻留在同一台机器上。

嵌入式数据库应用程序包括下列项目:

• 客户应用程序客户应用程序客户应用程序客户应用程序 这包括 Adaptive Server Anywhere 客户端要求。

有关部署客户应用程序的信息,请参阅 "" 部署客户端应用程序 " 第 422 页 "。

• 数据库服务器数据库服务器数据库服务器数据库服务器 Adaptive Server Anywhere 个人数据库服务器。

有关部署数据库服务器的信息,请参阅 "" 部署数据库服务器 " 第434 页 "。

• SQL Remote 如果您的应用程序使用 SQL Remote 复制,则必须

部署 "SQL Remote 消息代理 "。

• 数据库数据库数据库数据库 您必须部署保存着该应用程序所使用数据的数据库文

件。

部署个人服务器部署个人服务器部署个人服务器部署个人服务器

当您部署使用个人服务器的应用程序时,需要同时部署客户应用程序组件和数据库服务器组件。

语言资源库 (dblgen8.dll) 在客户端和服务器之间共享。您只需该文件

的一个副本。

建议您遵循 Adaptive Server Anywhere 安装行为,并将客户端和服务器

文件安装在同一目录中。

切记,如果您的应用程序在数据库中使用 Java,则提供 Java zip 文件和 Java DLL。

437

Page 452: Adaptive Server Anywhere

部署嵌入式数据库应用程序

部署数据库实用程序部署数据库实用程序部署数据库实用程序部署数据库实用程序

如果您需要将数据库实用程序 (如 dbbackup.exe)和应用程序一起部

署,则需要该实用程序可执行文件和下列附加文件:

注意注意注意注意 • 数据库工具是嵌入式 SQL 应用程序,您必须提供此类应用程序所

需的文件, "" 部署嵌入式 SQL 客户端 " 第 429 页 " 中列出了这些

文件。

• 对于 UNIX 上的多线程应用程序,请使用 libdbtools8_r.so 和 libdbtasks8_r.so。

部署部署部署部署 SQL Remote

如果要部署 "SQL Remote 消息代理 ",需要包括下列文件:

说明说明说明说明 Windows UNIX

数据库工具库 dbtool8.dll libdbtools8.so、 libdbtasks8.so

附加库 dbwtsp8.dll libdbwtsp8.so

语言资源库 dblgen8.dll dblgen8.res

" 连接 " 对话框 (只限 dbisqlc)

dbcon8.dll

说明说明说明说明 Windows UNIX

消息代理 dbremote.exe dbremote

数据库工具库 dbtool8.dll libdbtools8.so、 libdbtasks8.so

附加库 dbwtsp8.dll libdbwtsp8.so

语言资源库 dblgen8.dll dblgen8.res

VIM 消息链接库 1 dbvim8.dll

SMTP 消息链接库 1 dbsmtp8.dll

438

Page 453: Adaptive Server Anywhere

第 12 章 部署数据库和应用程序

1 只针对要使用的消息链接部署该库。

建议您遵循 Adaptive Server Anywhere 安装行为,并将 SQL Remote 文件

与 Adaptive Server Anywhere 文件安装在同一个目录中。

对于 UNIX 上的多线程应用程序,请使用 libdbtools8_r.so 和 libdbtasks8_r.so。

FILE 消息链接库 1 dbfile8.dll libdbfile8.so

FTP 消息链接库 1 dbftp8.dll

MAPI 消息链接库 1 dbmapi8.dll

接口库 dblib8.dll

说明说明说明说明 Windows UNIX

439

Page 454: Adaptive Server Anywhere

部署嵌入式数据库应用程序

440

Page 455: Adaptive Server Anywhere

第 13 章

SQL 预处理器错误消息预处理器错误消息预处理器错误消息预处理器错误消息

关于本章关于本章关于本章关于本章 本章将提供了所有 SQL 预处理器错误和警告的列表。

441

Page 456: Adaptive Server Anywhere

SQL 预处理器错误消息 (按错误消息值编索引)

SQL 预处理器错误消息(按错误消息值编索引)预处理器错误消息(按错误消息值编索引)预处理器错误消息(按错误消息值编索引)预处理器错误消息(按错误消息值编索引)

消息值消息值消息值消息值 消息消息消息消息

2601 " 预定值 %1 过大 " 第 462 页

2602 " 主机类型不支持组合指针和数

组 " 第 453 页

2603 " 对于字符类型,仅支持一维数

组 " 第 461 页

2604 "VARCHAR 类型必须有长度 " 第 451 页

2605 " 不支持 VARCHAR 数组 " 第452 页

2606 "VARCHAR 主机变量不能为指

针 " 第 451 页

2607 "VARCHAR 主机变量中不允许

初始化程序 " 第 457 页

2608 "FIXCHAR 类型必须有长度" 第448 页

2609 " 不支持 FIXCHAR 数组 " 第451 页

2610 " 不支持该类型的数组 " 第 452页

2611 " 对于 decimal 类型,必须指定

精度 " 第 461 页

2612 " 不允许十进制数组 " 第 452 页

2613 " 未知的 hostvar 类型 " 第 451 页

2614 " 无效整数 " 第 458 页

442

Page 457: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

2615 ""%1" 主机变量必须是 C 字符

串类型 " 第 447 页

2617 ""%1" 符号已经定义 " 第 447 页

2618 "SQL 语句变量的无效类型 " 第459 页

2619 " 找不到头文件 "%1"" 第 448 页

2620 " 主机变量 "%1" 未知 " 第 455页

2621 " 指示符变量 "%1" 未知 " 第 457页

2622 " 类型对于指示符变量 "%1" 无效 " 第 459 页

2623 ""%1" 上无效的主机变量类型 " 第 458 页

2625 " 主机变量 "%1" 有两个不同的

定义 " 第 455 页

2626 " 语句 "%1" 未被预先准备 " 第462 页

2627 " 之前未声明游标 "%1"" 第 453页

2628 " 未知语句 "%1"" 第 464 页

2629 " 该游标不允许主机变量 " 第455 页

2630 " 主机变量被指定了两次 - 在声

明和打开时 " 第 456 页

2631 " 必须指定主机列表或 %1 上的 using 子句 " 第 460 页

消息值消息值消息值消息值 消息消息消息消息

443

Page 458: Adaptive Server Anywhere

SQL 预处理器错误消息 (按错误消息值编索引)

2633 "SELECT 语句中没有 INTO 子句 " 第 460 页

2634 "SQL 语言用法不正确 -- 它是

"%1" 扩充 " 第 457 页

2635 " 嵌入式 SQL 语言用法不正确 -- 它是 "%1" 扩充 " 第 456 页

2636 " 错误的嵌入式 SQL 语法 " 第456 页

2637 " 缺少字符串的末尾引号 " 第459 页

2639 " 标识太长 " 第 462 页

2640 ""%1" 主机变量必须是整数类

型 " 第 447 页

2641 " 必须在 DESCRIBE 中指定一

个 SQLDA" 第 460 页

2642 " 指定了两个相同类型的 SQLDA (INTO 或 USING)" 第450 页

2646 " 无法描述静态游标 " 第 453 页

2647 " 不能重新定义宏 " 第 450 页

2648 " 无效数组维 " 第 450 页

2649 " 无效的描述符索引 " 第 458 页

2650 "SET DESCRIPTOR 的无效字段

" 第 458 页

2651 " 在 SET DESCRIPTOR 语句中

多次使用字段 " 第 454 页

消息值消息值消息值消息值 消息消息消息消息

444

Page 459: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

2652 " 数据值必须是主机变量 " 第453 页

2660 " 声明游标时不允许 Into 子句 - 忽略 " 第 450 页

2661 " 不识别的 SQL 语法 " 第 464 页

2662 " 未知的 sql 函数 "%1"" 第 463页

2663 "SQL 函数 "%1" 的参数数目不

正确 " 第 464 页

2664 " 如果被两个线程使用,静态语

句名将不能正常工作 " 第 462 页

2665 " 已经重定义了主机变量 "%1"" 第 455 页

2666 " 供应商扩充 " 第 464 页

2667 " 中等 SQL 功能 " 第 457 页

2668 " 全部 SQL 功能 " 第 454 页

2669 " 事务 SQL 扩充 " 第 463 页

2680 " 没有声明部分,也没有 INCLUDE SQLCA 语句 " 第 461页

2681 " 无法打开临时文件 " 第 463 页

2682 " 读取临时文件时出错 " 第 454页

2683 " 写入输出文件时出错 " 第 454页

2690 " 该游标的主机变量数目不一致

" 第 449 页

消息值消息值消息值消息值 消息消息消息消息

445

Page 460: Adaptive Server Anywhere

SQL 预处理器错误消息 (按错误消息值编索引)

2691 " 该游标的主机变量类型不一致

" 第 449 页

2692 " 该游标的指示符变量不一致 " 第 449 页

2693 " 在 UltraLite 中功能不可用 " 第448 页

2694 " 未对游标 "%1" 使用 OPEN" 第461 页

2695 " 未对游标 "%1" 使用 FETCH 或 PUT" 第 460 页

2696 " 主机变量 "%1" 已用不同指示

符使用多次 " 第 448 页

2697 "long binary/long varchar 大小限

制对于 UltraLite 为 65535" 第459 页

消息值消息值消息值消息值 消息消息消息消息

446

Page 461: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

SQLPP 错误错误错误错误

本节列出了由 SQL 预处理器生成的消息。这些消息可能是错误消息,

也可能是警告消息,这取决于命令行选项的设置。

有关 SQL 预处理器及其命令行选项的更多信息,请参阅 "SQL 预处理器

" 第 247 页。

"%1" 主机变量必须是主机变量必须是主机变量必须是主机变量必须是 C 字符串类型字符串类型字符串类型字符串类型

可能的原因可能的原因可能的原因可能的原因 嵌入式 SQL 语句中 (用于游标名称、选项名称等)需要 C 字符串,而

提供的值不是 C 字符串。

"%1" 主机变量必须是整数类型主机变量必须是整数类型主机变量必须是整数类型主机变量必须是整数类型

可能的原因可能的原因可能的原因可能的原因 您在仅允许整数类型主机变量的语句中使用了不是整数类型的主机变量。

"%1" 符号已经定义符号已经定义符号已经定义符号已经定义

可能的原因可能的原因可能的原因可能的原因 您对某个主机变量定义了两次。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2615 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2640 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2617 错误

447

Page 462: Adaptive Server Anywhere

SQLPP 错误

找不到头文件找不到头文件找不到头文件找不到头文件 "%1"

可能的原因可能的原因可能的原因可能的原因 未找到指定的头文件。请注意,预处理器将使用 INCLUDE 环境变量搜

索头文件。

FIXCHAR 类型必须有长度类型必须有长度类型必须有长度类型必须有长度

可能的原因可能的原因可能的原因可能的原因 您使用了 DECL_FIXCHAR 宏来声明 FIXCHAR 类型的主机变量,但是

没有指定长度。

在在在在 UltraLite 中功能不可用中功能不可用中功能不可用中功能不可用

可能的原因可能的原因可能的原因可能的原因 您使用了 UltraLite 不支持的功能。

主机变量主机变量主机变量主机变量 "%1" 已用不同指示符使用多次已用不同指示符使用多次已用不同指示符使用多次已用不同指示符使用多次

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2619 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2608 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2693 标志 (警告或错误)

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2696 错误

448

Page 463: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

可能的原因可能的原因可能的原因可能的原因 您在同一个语句中多次使用同一个主机变量,并带有不同的指示符变量。这不受支持。

该游标的主机变量类型不一致该游标的主机变量类型不一致该游标的主机变量类型不一致该游标的主机变量类型不一致

可能的原因可能的原因可能的原因可能的原因 您使用了一个主机变量,其类型或长度与以前用于该游标的类型或长度不同。游标的主机变量类型必须一致。

该游标的指示符变量不一致该游标的指示符变量不一致该游标的指示符变量不一致该游标的指示符变量不一致

可能的原因可能的原因可能的原因可能的原因 您使用的指示符变量与以前用于该游标的指示符变量不同,或者,您没有使用指示符变量,而以前该游标使用了指示符变量。游标的指示符变量用法必须一致。

该游标的主机变量数目不一致该游标的主机变量数目不一致该游标的主机变量数目不一致该游标的主机变量数目不一致

可能的原因可能的原因可能的原因可能的原因 您使用的主机变量的数目与游标以前使用的主机变量数目不同。游标的主机变量数目必须一致。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2691 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2692 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2690 错误

449

Page 464: Adaptive Server Anywhere

SQLPP 错误

声明游标时不允许声明游标时不允许声明游标时不允许声明游标时不允许 Into 子句子句子句子句 - 忽略忽略忽略忽略

可能的原因可能的原因可能的原因可能的原因 您在 DECLARE CURSOR 语句上使用了 INTO 子句。 INTO 子句将被忽

略。

无效数组维无效数组维无效数组维无效数组维

可能的原因可能的原因可能的原因可能的原因 该变量的数组维为负值。

不能重新定义宏不能重新定义宏不能重新定义宏不能重新定义宏

可能的原因可能的原因可能的原因可能的原因 某个预处理器宏被定义了两次,有可能是在头文件中。

指定了两个相同类型的指定了两个相同类型的指定了两个相同类型的指定了两个相同类型的 SQLDA ((((INTO 或或或或 USING)

可能的原因可能的原因可能的原因可能的原因 您为此语句指定了两个 INTO DESCRIPTOR 或两个 USING DESCRIPTOR 子句。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2660 警告

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2648 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2647 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2642 错误

450

Page 465: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

未知的未知的未知的未知的 hostvar 类型类型类型类型

可能的原因可能的原因可能的原因可能的原因 您声明了 SQL 预处理器不理解的主机变量类型。

VARCHAR 主机变量不能为指针主机变量不能为指针主机变量不能为指针主机变量不能为指针

可能的原因可能的原因可能的原因可能的原因 您尝试将主机变量声明为 VARCHAR 或 BINARY 类型的指针。这不是

合法的主机变量类型。

VARCHAR 类型必须有长度类型必须有长度类型必须有长度类型必须有长度

可能的原因可能的原因可能的原因可能的原因 您尝试使用 DECL_VARCHAR 或 DECL_BINARY 宏声明 VARCHAR 或 BINARY 主机变量,但是没有指定数组的大小。

不支持不支持不支持不支持 FIXCHAR 数组数组数组数组

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2613 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2606 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2604 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2609 错误

451

Page 466: Adaptive Server Anywhere

SQLPP 错误

可能的原因可能的原因可能的原因可能的原因 您尝试将主机变量声明为某个 FIXCHAR 数组。这不是合法的主机变量

类型。

不支持不支持不支持不支持 VARCHAR 数组数组数组数组

可能的原因可能的原因可能的原因可能的原因 您尝试将主机变量声明为 VARCHAR 或 BINARY 数组。这不是合法的

主机变量类型。

不允许十进制数组不允许十进制数组不允许十进制数组不允许十进制数组

可能的原因可能的原因可能的原因可能的原因 您尝试将主机变量声明为 DECIMAL 数组。十进制数组不是合法的主机

变量类型。

不支持该类型的数组不支持该类型的数组不支持该类型的数组不支持该类型的数组

可能的原因可能的原因可能的原因可能的原因 您尝试声明的主机变量数组类型不受支持。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2605 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2612 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2610 错误

452

Page 467: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

无法描述静态游标无法描述静态游标无法描述静态游标无法描述静态游标

可能的原因可能的原因可能的原因可能的原因 您描述了静态游标。描述游标时,游标名称必须在主机变量中指定。

主机类型不支持组合指针和数组主机类型不支持组合指针和数组主机类型不支持组合指针和数组主机类型不支持组合指针和数组

可能的原因可能的原因可能的原因可能的原因 您将指针的数组用作主机变量。这是不合法的。

之前未声明游标之前未声明游标之前未声明游标之前未声明游标 "%1"

可能的原因可能的原因可能的原因可能的原因 使用了未首先声明的嵌入式 SQL 游标名称 (在 FETCH、 OPEN、

CLOSE 等中)。

数据值必须是主机变量数据值必须是主机变量数据值必须是主机变量数据值必须是主机变量

可能的原因可能的原因可能的原因可能的原因 SET DESCRIPTOR 语句中使用的变量未声明为主机变量。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2646 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2602 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2627 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2652 错误

453

Page 468: Adaptive Server Anywhere

SQLPP 错误

读取临时文件时出错读取临时文件时出错读取临时文件时出错读取临时文件时出错

可能的原因可能的原因可能的原因可能的原因 从临时文件读取时发生错误。

写入输出文件时出错写入输出文件时出错写入输出文件时出错写入输出文件时出错

可能的原因可能的原因可能的原因可能的原因 向输出文件写入时发生错误。

在在在在 SET DESCRIPTOR 语句中多次使用字段语句中多次使用字段语句中多次使用字段语句中多次使用字段

可能的原因可能的原因可能的原因可能的原因 在一个 SET DESCRIPTOR 语句中多次使用了同一个关键字。

全部全部全部全部 SQL 功能功能功能功能

可能的原因可能的原因可能的原因可能的原因 您使用了全部 SQL/92 功能,并用 -ee、 -ei、 -we 或 -wi 标志命令行开关

进行了预处理。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2682 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2683 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2651 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2668 标志 (警告或错误)

454

Page 469: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

已经重定义了主机变量已经重定义了主机变量已经重定义了主机变量已经重定义了主机变量 "%1"

可能的原因可能的原因可能的原因可能的原因 您使用不同的主机类型重新定义了同一个主机变量。对于预处理器来说,主机变量是全局性的;两个不同类型的主机变量不能具有相同名称。

主机变量主机变量主机变量主机变量 "%1" 有两个不同的定义有两个不同的定义有两个不同的定义有两个不同的定义

可能的原因可能的原因可能的原因可能的原因 在同一个模块中,相同的主机变量名称定义了两种不同的类型。请注意,主机变量名称对于 C 模块来说是全局性的。

主机变量主机变量主机变量主机变量 "%1" 未知未知未知未知

可能的原因可能的原因可能的原因可能的原因 您在语句中使用了某个主机变量,而该主机变量未在声明部分中声明。

该游标不允许主机变量该游标不允许主机变量该游标不允许主机变量该游标不允许主机变量

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2665 警告

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2625 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2620 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2629 错误

455

Page 470: Adaptive Server Anywhere

SQLPP 错误

可能的原因可能的原因可能的原因可能的原因 对于指定的游标,声明语句上不允许有主机变量。如果游标名称是通过主机变量提供的,则您应使用完全动态 SQL,并准备该语句。准备好的

语句中可能已具有主机变量。

主机变量被指定了两次主机变量被指定了两次主机变量被指定了两次主机变量被指定了两次 - 在声明和打开时在声明和打开时在声明和打开时在声明和打开时

可能的原因可能的原因可能的原因可能的原因 您同时在声明语句和打开语句中指定了游标的主机变量。在静态情况下,您应该在声明语句上指定主机变量。在动态情况下,您应该在打开语句上指定主机变量。

嵌入式嵌入式嵌入式嵌入式 SQL 语言用法不正确语言用法不正确语言用法不正确语言用法不正确 -- 它是它是它是它是 "%1" 扩充扩充扩充扩充

错误的嵌入式错误的嵌入式错误的嵌入式错误的嵌入式 SQL 语法语法语法语法

可能的原因可能的原因可能的原因可能的原因 嵌入式 SQL 特定语句 (OPEN、 DECLARE、 FETCH 等)具有语法错

误。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2630 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2635 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2636 错误

456

Page 471: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

SQL 语言用法不正确语言用法不正确语言用法不正确语言用法不正确 -- 它是它是它是它是 "%1" 扩充扩充扩充扩充

指示符变量指示符变量指示符变量指示符变量 "%1" 未知未知未知未知

可能的原因可能的原因可能的原因可能的原因 您在语句中使用了指示符变量,但是该指示符变量未在声明部分声明。

VARCHAR 主机变量中不允许初始化程序主机变量中不允许初始化程序主机变量中不允许初始化程序主机变量中不允许初始化程序

可能的原因可能的原因可能的原因可能的原因 您不能为 VARCHAR 或 BINARY 类型的主机变量指定 C 变量初始化程

序。必须在常规的 C 可执行代码中对此变量进行初始化。

中等中等中等中等 SQL 功能功能功能功能

可能的原因可能的原因可能的原因可能的原因 您使用了中间 SQL/92 功能,并用 -ee 或 -we 标志命令行开关进行了预

处理。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2634 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2621 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2607 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2667 标志 (警告或错误)

457

Page 472: Adaptive Server Anywhere

SQLPP 错误

无效的描述符索引无效的描述符索引无效的描述符索引无效的描述符索引

可能的原因可能的原因可能的原因可能的原因 您使用 ALLOCATE DESCRIPTOR 语句分配的变量少于一个。

SET DESCRIPTOR 的无效字段的无效字段的无效字段的无效字段

可能的原因可能的原因可能的原因可能的原因 在 SET DESCRIPTOR 语句中使用了无效或未知的关键字。关键字只能

是 TYPE、 PRECISION、 SCALE、 LENGTH、 INDICATOR 或 DATA。

"%1" 上无效的主机变量类型上无效的主机变量类型上无效的主机变量类型上无效的主机变量类型

可能的原因可能的原因可能的原因可能的原因 在预处理器需要字符串类型的主机变量的位置,您使用了不是字符串类型的主机变量。

无效整数无效整数无效整数无效整数

可能的原因可能的原因可能的原因可能的原因 嵌入式 SQL 语句中要求整数 (用于读取偏移或者主机变量数组索引

等),而预处理器未能将提供的内容转换成整数。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2649 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2650 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2623 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2614 错误

458

Page 473: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

类型对于指示符变量类型对于指示符变量类型对于指示符变量类型对于指示符变量 "%1" 无效无效无效无效

可能的原因可能的原因可能的原因可能的原因 指示符变量必须是短整数类型。您将其它类型的变量用作了指示符变量。

SQL 语句变量的无效类型语句变量的无效类型语句变量的无效类型语句变量的无效类型

可能的原因可能的原因可能的原因可能的原因 用作语句标识符的主机变量类型应为 a_sql_statement_number。您尝试

将其它类型的主机变量用作语句标识符。

long binary/long varchar 大小限制对于大小限制对于大小限制对于大小限制对于 UltraLite 为为为为 65535

可能的原因可能的原因可能的原因可能的原因 在对 UltraLite 使用 DECL_LONGBINARY 或 DECL_LONGVARCHAR 时,数组的 大大小为 64K。

缺少字符串的末尾引号缺少字符串的末尾引号缺少字符串的末尾引号缺少字符串的末尾引号

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2622 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2618 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2697 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2637 错误

459

Page 474: Adaptive Server Anywhere

SQLPP 错误

可能的原因可能的原因可能的原因可能的原因 您在嵌入式 SQL 语句中指定了字符串常量,但是在行结束或文件结束

前没有末尾引号。

必须指定主机列表或必须指定主机列表或必须指定主机列表或必须指定主机列表或 %1 上的上的上的上的 using 子句子句子句子句

可能的原因可能的原因可能的原因可能的原因 特定的语句要求主机变量在主机变量表中指定,或者从 SQLDA 指定。

必须在必须在必须在必须在 DESCRIBE 中指定一个中指定一个中指定一个中指定一个 SQLDA

未对游标未对游标未对游标未对游标 "%1" 使用使用使用使用 FETCH 或或或或 PUT

可能的原因可能的原因可能的原因可能的原因 游标已声明并打开,但尚未使用过。

SELECT 语句中没有语句中没有语句中没有语句中没有 INTO 子句子句子句子句

可能的原因可能的原因可能的原因可能的原因 您指定了嵌入式静态 SELECT 语句,但未为结果指定 INTO 子句。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2631 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2641 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2695 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2633 错误

460

Page 475: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

未对游标未对游标未对游标未对游标 "%1" 使用使用使用使用 OPEN

可能的原因可能的原因可能的原因可能的原因 游标已声明,可能也已使用,但尚未打开过。

没有声明部分,也没有没有声明部分,也没有没有声明部分,也没有没有声明部分,也没有 INCLUDE SQLCA 语句语句语句语句

可能的原因可能的原因可能的原因可能的原因 源文件中缺少 EXEC SQL INCLUDE SQLCA 语句。

对于字符类型,仅支持一维数组对于字符类型,仅支持一维数组对于字符类型,仅支持一维数组对于字符类型,仅支持一维数组

可能的原因可能的原因可能的原因可能的原因 您尝试将主机变量声明为某个字符数组。这不是合法的主机变量类型。

对于对于对于对于 decimal 类型,必须指定精度类型,必须指定精度类型,必须指定精度类型,必须指定精度

可能的原因可能的原因可能的原因可能的原因 使用 DECL_DECIMAL 宏声明压缩的十进制主机变量时必须指定精度。

小数位数是可选的。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2694 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2680 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2603 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2611 错误

461

Page 476: Adaptive Server Anywhere

SQLPP 错误

语句语句语句语句 "%1" 未被预先准备未被预先准备未被预先准备未被预先准备

可能的原因可能的原因可能的原因可能的原因 在没有事先准备的情况下,使用了嵌入式 SQL 语句 (EXECUTE)。

如果被两个线程使用,静态语句名将不能正常工作如果被两个线程使用,静态语句名将不能正常工作如果被两个线程使用,静态语句名将不能正常工作如果被两个线程使用,静态语句名将不能正常工作

可能的原因可能的原因可能的原因可能的原因 您使用了静态语句名称,并用 -r 再入式命令行开关进行了预处理。静态

语句名称导致生成的静态变量由数据库进行填充。如果两个线程使用相同的语句,则会引起此变量的争用。应使用本地主机变量作为语句标识符,而不是静态名称。

预定值预定值预定值预定值 %1 过大过大过大过大

可能的原因可能的原因可能的原因可能的原因 您尝试编索引的主机变量的数组值对于该数组来说太大。

标识太长标识太长标识太长标识太长

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2626 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2664 警告

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2601 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2639 错误

462

Page 477: Adaptive Server Anywhere

第 13 章 SQL 预处理器错误消息

可能的原因可能的原因可能的原因可能的原因 SQL 预处理器的标记的 大长度为 2K。任何长于 2K 的标识都将产生

此错误。对于嵌入式 SQL 命令中 (此错误发生的主要位置)的常量字

符串应使用字符串串联,以形成更长的字符串。

事务事务事务事务 SQL 扩充扩充扩充扩充

可能的原因可能的原因可能的原因可能的原因 您使用了 "Sybase 事务 SQL" 功能,该功能未由 SQL/92 定义,也未用 -ee、 -ei、 -ef、 -we、 -wi 或 -wf 标志命令行开关进行预处理。

无法打开临时文件无法打开临时文件无法打开临时文件无法打开临时文件

可能的原因可能的原因可能的原因可能的原因 尝试打开临时文件时发生错误。

未知的未知的未知的未知的 sql 函数函数函数函数 "%1"

可能的原因可能的原因可能的原因可能的原因 您使用的某个 SQL 函数对于预处理器来说是未知的,在该语句被发送

到数据库引擎时可能会导致错误。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2669 标志 (警告或错误)

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2681 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2662 警告

463

Page 478: Adaptive Server Anywhere

SQLPP 错误

未知语句未知语句未知语句未知语句 "%1"

可能的原因可能的原因可能的原因可能的原因 您尝试删除的嵌入式 SQL 语句不存在。

不识别的不识别的不识别的不识别的 SQL 语法语法语法语法

可能的原因可能的原因可能的原因可能的原因 您使用的某个 SQL 语句在被发送到数据库引擎时可能会导致语法错误。

供应商扩充供应商扩充供应商扩充供应商扩充

可能的原因可能的原因可能的原因可能的原因 您使用的某个 Adaptive Server Anywhere 功能未由 SQL/92 定义,也未用 -ee、 -ei、 -ef、 -we、 -wi 或 -wf 标志命令行开关进行预处理。

SQL 函数函数函数函数 "%1" 的参数数目不正确的参数数目不正确的参数数目不正确的参数数目不正确

可能的原因可能的原因可能的原因可能的原因 您使用的某个 SQL 函数的参数数目不正确。这样有可能在把该语句发

送到数据库引擎时导致错误。

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2628 错误

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2661 警告

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2666 标志 (警告或错误)

消息值消息值消息值消息值 消息类型消息类型消息类型消息类型

2663 警告

464

Page 479: Adaptive Server Anywhere

索引索引索引索引索引索引索引索引

字母字母字母字母>>

数据库中的 Java 方法 73

a_backup_db 结构 334a_change_log 结构 336a_compress_db 结构 338a_compress_stats 结构 339a_create_db 结构 340a_crypt_db 结构 342a_db_collation 结构 343a_db_info 结构 345a_dblic_info 结构 347a_dbtools_info 结构 348a_name 结构 351a_stats_line 结构 352a_sync_db 结构 352a_syncpub 结构 354a_sysinfo 结构 355a_table_info 结构 356a_translate_log 结构 357a_truncate_log 结构 358a_validate_db 结构 362a_validate_type 枚举 368a_writefile 结构 364ActiveX 数据对象

关于 374

ADOCommand 对象 376

Connection 对象 374

Recordset 对象 377, 378

编程简介 3查询 377, 378

更新 379

关于 374

连接 374

命令 376

游标 27, 379

游标类型 25

在应用程序中使用 SQL 语句 10

alloc_sqlda 函数关于 251

alloc_sqlda_noind 函数关于 251

ALTER DATABASE 语句数据库中的 Java 96, 97

an_erase_db 结构 349an_expand_db 结构 350an_unload_db 结构 359an_upgrade_db 结构 361ARRAY 子句

FETCH 语句 214

asademo.db 文件关于 xii

asajdbc.zip部署数据库服务器 434

运行时类 94

ASAJDBCDRV JAR 文件关于 95

ASAJRT JAR 文件关于 95

asajrt12.zip运行时类 94

ASAProvOLE DB 提供程序 372

ASASystem JAR 文件关于 95

BINARY 数据类型

465

Page 480: Adaptive Server Anywhere

索引索引索引索引

嵌入式 SQL 197

BLOB嵌入式 SQL 235

在嵌入式 SQL 中发送 238

在嵌入式 SQL 中检索 236

Borland C++支持 180

C 编程语言数据类型 197

CALL 语句嵌入式 SQL 241

catch 块Java 70

CD-ROM部署数据库 435

CHAINED 选项JDBC 159

Class.forName 方法装载 jConnect 148

classes.zip部署数据库服务器 434

运行时类 94

CLASSPATH 环境变量jConnect 146

关于 78

设置 156

数据库中的 Java 78

CLOSE 语句关于 211

com.sybase 包运行时类 94

Command 对象ADO 376

COMMIT 语句JDBC 159

游标 48

自动提交模式 46

compareTo 方法

466

对象比较 117

COMPUTE 子句CREATE TABLE 133

Connection 对象ADO 374

console 实用程序部署 433

CREATE DATABASE 语句数据库中的 Java 96, 97

CREATE PROCEDURE 语句嵌入式 SQL 241

CS_CSR_ABS 396CS_CSR_FIRST 396CS_CSR_LAST 396CS_CSR_PREV 396CS_CSR_REL 396CS_DATA_BOUNDARY 396CS_DATA_SENSITIVITY 396CS_PROTO_DYNPROC 396CS_REG_NOTIF 396CS_REQ_BCP 396

ct_command 函数Open Client 392, 394

ct_cursor 函数Open Client 393

ct_dynamic 函数Open Client 392

ct_results 函数Open Client 394

ct_send 函数Open Client 394

db_backup 函数关于 245, 251

DB_BACKUP_CLOSE_FILE 参数 251DB_BACKUP_END 参数 251DB_BACKUP_OPEN_FILE 参数 251DB_BACKUP_READ_PAGE 参数 251DB_BACKUP_READ_RENAME_LOG 参数

251DB_BACKUP_START 参数 251

Page 481: Adaptive Server Anywhere

索引索引索引索引

DB_CALLBACK_CONN_DROPPED 回调参数260

DB_CALLBACK_DEBUG_MESSAGE 回调参数 260

DB_CALLBACK_FINISH 回调参数 260DB_CALLBACK_MESSAGE 回调参数 261DB_CALLBACK_START 回调参数 260DB_CALLBACK_WAIT 回调参数 260db_cancel_request 函数

关于 255

请求管理 245

db_delete_file 函数关于 255

db_find_engine 函数关于 256

db_fini 函数关于 256

db_fini_dll调用 184

db_get_property 函数关于 257

db_init 函数关于 257

db_init_dll调用 184

db_is_working 函数关于 258

请求管理 245

db_locate_servers 函数关于 258

db_register_a_callback 函数关于 259

请求管理 245

db_start_database 函数关于 262

db_start_engine 函数关于 262

db_stop_database 函数关于 264

db_stop_engine 函数

关于 264

db_string_connect 函数关于 265

db_string_disconnect 函数关于 266

db_string_ping_server 函数关于 266

DBBackup 函数 320DBChangeLogName 函数 320DBChangeWriteFile 函数 321DBCollate 函数 321DBCompress 函数 322dbcon8.dll

部署 ODBC 客户端 424

部署 OLE DB 客户端 422

部署嵌入式 SQL 客户端 430

部署数据库实用程序 438

dbconsole 实用程序部署 433

DBCreate 函数 322DBCreateWriteFile 函数 323DBCrypt 函数 324dbctrs8.dll

部署数据库服务器 434

dbeng8部署数据库服务器 434

DBErase 函数 324DBExpand 函数 325dbextf.dll

部署数据库服务器 434

dbfile.dll部署 SQL Remote 438

DBInfo 函数 325DBInfoDump 函数 326DBInfoFree 函数 326dbinit 实用程序

数据库中的 Java 96, 97

dbipx8.dll部署 ODBC 客户端 424

部署嵌入式 SQL 客户端 430

467

Page 482: Adaptive Server Anywhere

索引索引索引索引

dbjava8.dll部署数据库服务器 434

dblgen8.dll部署 ODBC 客户端 424

部署 OLE DB 客户端 422

部署 SQL Remote 438

部署嵌入式 SQL 客户端 430

部署数据库服务器 434

部署数据库实用程序 438

dblib8.dll接口库 178

DBLicense 函数 327dbmapi.dll

部署 SQL Remote 438

dbmlsync 实用程序C API 352

构建自己的 352

dbodbc8.dll部署 ODBC 客户端 424

dbodbc8.libWindows CE ODBC 导入库 280

dbodbc8.soUNIX ODBC 驱动程序 281

dboledb8.dll部署 OLE DB 客户端 422

dboledba8.dll部署 OLE DB 客户端 422

dbremote部署 SQLRemote 438

dbserv8.dll部署数据库服务器 434

dbsmtp.dll部署 SQL Remote 438

dbsrv8部署数据库服务器 434

DBStatusWriteFile 函数 328DBSynchronizeLog 函数 328dbtool8.dll

Windows CE 310

468

部署 SQL Remote 438

部署数据库实用程序 438

DBTools 接口调用 DBTools 函数 312

关于 309

函数 320

简介 310

枚举 366

启动 311

使用 311

示例程序 316

完成 311

DBToolsFini 函数 329DBToolsInit 函数 329DBToolsVersion 函数 330dbtran_userlist_type 枚举 367DBTranslateLog 函数 331DBTruncateLog 函数 331DBUnload 函数 332dbunload 类型枚举 367dbunload 实用程序

构建自己的 359

头文件 359

dbupgrad 实用程序数据库中的 Java 96, 97

DBUpgrade 函数 332DBValidate 函数 333dbvim.dll

部署 SQL Remote 438

dbwtsp8.dll部署 SQL Remote 438

部署数据库实用程序 438

dbxtract 实用程序构建自己的 359

数据库工具接口 332

头文件 359

DECIMAL 数据类型嵌入式 SQL 197

DECL_BINARY 宏 197

Page 483: Adaptive Server Anywhere

索引索引索引索引

DECL_DECIMAL 宏 197DECL_FIXCHAR 宏 197DECL_LONGBINARY 宏 197DECL_LONGVARCHAR 宏 197DECL_VARCHAR 宏 197DECLARE 语句

关于 211

DELETE 语句定位 23

数据库对象中的 Java 113

DESCRIBE 语句SQLDA 字段 227

sqllen 字段 230

sqltype 字段 230

多个结果集 244

关于 222

DISTINCT 关键字数据库列中的 Java 117

DLL多个 SQLCA 208

DLL 入口点 251DT_BIGINT 嵌入式 SQL 数据类型 192DT_BINARY 嵌入式 SQL 数据类型 193DT_BIT 嵌入式 SQL 数据类型 192DT_DATE 嵌入式 SQL 数据类型 192DT_DECIMAL 嵌入式 SQL 数据类型 192DT_DOUBLE 嵌入式 SQL 数据类型 192DT_FIXCHAR 嵌入式 SQL 数据类型 193DT_FLOAT 嵌入式 SQL 数据类型 192DT_INT 嵌入式 SQL 数据类型 192DT_LONGBINARY 嵌入式 SQL 数据类型 194DT_LONGVARCHAR 嵌入式 SQL 数据类型

193DT_SMALLINT 嵌入式 SQL 数据类型 192DT_STRING 数据类型 269DT_TIME 嵌入式 SQL 数据类型 192DT_TIMESTAMP 嵌入式 SQL 数据类型 193DT_TIMESTAMP_STRUCT 嵌入式 SQL 数据

类型 194DT_TINYINT 嵌入式 SQL 数据类型 192DT_UNSINT 嵌入式 SQL 数据类型 192

DT_UNSSMALLINT 嵌入式 SQL 数据类型192

DT_VARCHAR 嵌入式 SQL 数据类型 193DT_VARIABLE 嵌入式 SQL 数据类型 194, 195DTC

三层计算 401

DYNAMIC SCROLL 游标关于 25, 37

嵌入式 SQL 27

疑难解答 20

EAServer分布式事务 406

三层计算 401

事务处理协调器 406

组件事务属性 407

EXEC SQL嵌入式 SQL 开发 183

EXECUTE 语句 220嵌入式 SQL 中的存储过程 241

executeQuery 方法关于 165

executeUpdate JDBC 方法 14关于 162

FETCH 语句动态查询 222

多行 214

关于 210, 211

宽 214

fill_s_sqlda 函数关于 267

fill_sqlda 函数关于 267

finally 块Java 70

FIXCHAR 数据类型嵌入式 SQL 197

ForceStart [FORCESTART] 连接参数db_start_engine 263

free_filled_sqlda 函数

469

Page 484: Adaptive Server Anywhere

索引索引索引索引

关于 267

free_sqlda 函数关于 268

free_sqlda_noind 函数关于 268

getConnection 方法实例 159

getObject 方法使用 172

-gn 选项线程 121

GNU 编译器支持 180

GRANT 语句JDBC 169

GROUP BY 子句数据库列中的 Java 117

import 语句Java 68

数据库中的 Java 77

INCLUDE 语句SQLCA 204

INOUT 参数数据库中的 Java 124

INSERT 语句JDBC 162, 163

对象 168

多行 214

宽 214

数据库中的 Java 109

性能 12

INSTALL 语句简介 72

类版本 129

使用 101, 102

InstallShield部署 Adaptive Server Anywhere 416

静默安装 418

470

Interactive SQL部署 433

JaguarEAServer 406

JAR 和 ZIP 文件创建向导使用 102

JAR 文件Java 68

安装 100, 102

版本 103

更新 103

删除 113

添加 102

Javacatch 块 70

finally 块 70

JDBC 140

try 块 70

查询对象 170

错误处理 69

构造函数 69

接口 69

类 67

析构函数 69

Java 2支持的版本 71

Java 安全管理关于 126

java 包运行时类 94

Java 存储过程关于 122

示例 123

Java 类安装 101

添加 101

Java 类创建向导使用 81, 101, 158

Page 485: Adaptive Server Anywhere

索引索引索引索引

Java 数据类型插入 168

检索 168

JAVA_HEAP_SIZE 选项使用 137

JAVA_NAMESPACE_SIZE 选项使用 137

jcatalog.sql 文件jConnect 147

jConnectCLASSPATH 环境变量 146

URL 148

包 147

部署 JDBC 客户端 431

关于 146

连接 153, 157

数据库设置 147

提供的版本 146

系统对象 147

选择 JDBC 驱动程序 141

装载 148

JDBC2.0 版的功能 142, 143

INSERT 语句 162, 163

jConnect 146

prepared 语句 166

SELECT 语句 165

SQL 语句 10

版本 71, 142, 143

部署 JDBC 客户端 431

非标准类 142, 143

服务器端 145

服务器端连接 157

关于 140

简介 5客户端 145

客户端连接 153

连接 145, 153

连接代码 153

连接到数据库 149

连接缺省值 159

权限 169

使用方式 140

示例 140, 153

数据访问 161

要求 140

应用程序概述 141

游标类型 25

运行时类 94

自动提交 159

自动提交模式 46

JDBC 驱动程序兼容性 141

性能 141

选择 141

JDBCExamples 类关于 161

JDBCExamples.java 文件 140JDBC-ODBC Bridge

部署 JDBC 客户端 431

连接 151

使用 151

所需文件 151

选择 JDBC 驱动程序 141

jdemo.sql示例表 90

JDK版本 71, 94

定义 58

LONG BINARY 数据类型嵌入式 SQL 197, 235

在嵌入式 SQL 中发送 238

在嵌入式 SQL 中检索 236

LONG VARCHAR 数据类型

471

Page 486: Adaptive Server Anywhere

索引索引索引索引

嵌入式 SQL 197, 235

在嵌入式 SQL 中发送 238

在嵌入式 SQL 中检索 236

main 方法数据库中的 Java 75, 120

MAX 函数数据库列中的 Java 117

Microsoft Transaction Server三层计算 401

Microsoft Visual C++支持 180

MIN 函数数据库列中的 Java 117

mlxtract 实用程序构建自己的 359

头文件 359

MobiLink 同步服务器部署 418

MSDASQLOLE DB 提供程序 372

NetWare嵌入式 SQL 程序 185

NLM嵌入式 SQL 程序 185

NO SCROLL 游标关于 25, 35

嵌入式 SQL 27

ntodbc.h关于 278

NULL动态 SQL 225

指示符变量 200

ODBCprepared 语句 296

SQL 语句 10

UNIX 开发 280, 282

Windows CE 279, 280

编程 275

472

编程简介 2部署 423

存储过程 304

错误检查 306

导入库 278

多个结果集 304

多线程应用程序 293

兼容性 277

简介 276

结果集 304

句柄 286

链接 278

没有驱动程序管理器 282

驱动程序部署 424

示例程序 283

示例应用程序 288

数据源 427

头文件 278

向后兼容 277

游标 27, 299

游标类型 25

支持 276

支持的版本 276

注册表项 427

自动提交模式 46

ODBC 驱动程序UNIX 281

ODBC 设置部署 424, 426

odbc.h关于 278

OLE DBAdaptive Server Anywhere 372

ODBC 和 372

编程简介 3部署 422

更新 379

Page 487: Adaptive Server Anywhere

索引索引索引索引

关于 372

提供程序部署 422

游标 27, 379

游标类型 25

支持的接口 382

支持的平台 372

OLE 事务三层计算 400

Open ClientAdaptive Server Anywhere 限制 396

SQL 392

SQL 语句 10

部署 Open Client 应用程序 432

简介 6接口 387

数据类型 389

数据类型范围 390

数据类型兼容性 389

限制 396

要求 388

游标类型 25

自动提交模式 46

OPEN 语句关于 211

ORDER BY 子句数据库列中的 Java 117

OUT 参数数据库中的 Java 124

PREFETCH 选项游标 42

PREPARE TRANSACTION 语句和 Open Client 396

PREPARE 语句 220Prepared 语句

Open Client 392

prepared 语句JDBC 166

ODBC 296

数据库对象中的 Java 111

PreparedStatement 接口关于 166

PreparedStatement 类setObject 方法 111

prepareStatement 方法 14println 方法

数据库中的 Java 75

privateJava 访问 68

protectedJava 68

Java 访问 68

publicJava 访问 68

PUT 操作 23PUT 语句 23

多行 214

宽 214

QUOTED_IDENTIFIER 选项jConnect 设置 150

Recordset 对象ADO 377, 378

REMOTEPWD使用 149

ROLLBACK TO SAVEPOINT 语句游标 49

ROLLBACK 语句游标 48

rt.jar运行时类 94

SCROLL 游标关于 25, 38

嵌入式 SQL 27

SecurityManager 类关于 125, 126

SELECT 语句JDBC 165

单行 210

473

Page 488: Adaptive Server Anywhere

索引索引索引索引

动态 222

对象 168

数据库中的 Java 114

setAutocommit 方法关于 159

setObject 方法使用 172

sp_tsql_environment 系统过程设置用于 jConnect 的选项 150

spt_mda 存储过程设置用于 jConnect 的选项 150

SQLADO 应用程序 10

JDBC 应用程序 10

ODBC 应用程序 10

Open Client 应用程序 10

嵌入式 SQL 应用程序 10

应用程序 10

SQL Anywhere Studio文档 vii

SQL Remote部署 438

数据库对象中的 Java 128

SQL 通信区域关于 204

SQL 语句执行 392

SQL 预处理器关于 247

命令行 247

运行 180

SQL/92SQL 预处理器 248

SQL_ATTR_MAX_LENGTH 属性关于 300

SQL_CALLBACK 类型声明 259SQL_CALLBACK_PARM 类型声明 259SQL_ERROR

474

ODBC 返回代码 306

SQL_INVALID_HANDLEODBC 返回代码 306

SQL_NEED_DATAODBC 返回代码 306

sql_needs_quotes 函数关于 268

SQL_NO_DATA_FOUNDODBC 返回代码 306

SQL_SUCCESSODBC 返回代码 306

SQL_SUCCESS_WITH_INFOODBC 返回代码 306

SQL92SQL 预处理器 248

SQLAllocHandle ODBC 函数关于 286

捆绑参数 295

使用 287

执行语句 294

SQLBindCol ODBC 函数关于 299, 300

SQLBindParameter ODBC 函数 13prepared 语句 296

存储过程 304

关于 295

SQLBrowseConnect ODBC 函数关于 290

SQLCA长度 204

多个 207, 208

更改 207

关于 204

线程 207

字段 204

sqlcabc SQLCA 字段关于 204

sqlcaid SQLCA 字段

Page 489: Adaptive Server Anywhere

索引索引索引索引

关于 204

sqlcode SQLCA 字段关于 204

SQLConnect ODBC 函数关于 290

SQLCOUNTsqlerror SQLCA 字段元素 205

sqld SQLDA 字段关于 226

SQLDAsqllen 字段 229

分配 251

关于 220, 225

描述符 44

释放 267

填充 267

主机变量 227

字段 226

字符串 267

sqlda_storage 函数关于 269

sqlda_string_length 函数关于 269

sqldabc SQLDA 字段关于 226

sqldaif SQLDA 字段关于 226

sqldata SQLDA 字段关于 227

sqldef.h数据类型 192

SQLDriverConnect ODBC 函数关于 290

sqlerrd SQLCA 字段关于 205

sqlerrmc SQLCA 字段关于 204

sqlerrml SQLCA 字段

关于 204

SQLError ODBC 函数关于 306

sqlerror SQLCA 字段SQLCOUNT 205

SQLIOCOUNT 205

SQLIOESTIMATE 206

元素 205

sqlerror_message 函数关于 269

sqlerrp SQLCA 字段关于 205

SQLExecDirect ODBC 函数关于 294

捆绑参数 295

SQLExecute ODBC 函数 13SQLExtendedFetch ODBC 函数

存储过程 304

关于 300

SQLFetch ODBC 函数存储过程 304

关于 300

SQLFreeHandle ODBC 函数使用 287

SQLFreeStmt ODBC 函数 13SQLGetData ODBC 函数

关于 299, 300

sqlind SQLDA 字段关于 227

SQLIOCOUNTsqlerror SQLCA 字段元素 205

SQLIOESTIMATEsqlerror SQLCA 字段元素 206

SQLJ 标准关于 52

sqllen SQLDA 字段DESCRIBE 语句 230

发送值 231

关于 227, 229

475

Page 490: Adaptive Server Anywhere

索引索引索引索引

检索值 232

说明值 230

sqlname SQLDA 字段关于 227

SQLNumResultCols ODBC 函数存储过程 304

SQLPP关于 178

命令行 247

SQLPrepare ODBC 函数 13关于 296

SQLRETURNODBC 返回代码类型 306

SQLSetConnectAttr ODBC 函数关于 292

SQLSetPos ODBC 函数关于 302

SQLSetStmtAttr ODBC 函数游标特性 299

sqlstate SQLCA 字段关于 205

SQLTransact ODBC 函数关于 288

sqltype SQLDA 字段DESCRIBE 语句 230

关于 227

sqlvar SQLDA 字段关于 226, 227

内容 227

sqlwarn SQLCA 字段关于 205

START JAVA 语句使用 137

STOP JAVA 语句使用 137

sun 包运行时类 94

Sybase Central部署 433

476

添加 JAR 文件 102

添加 Java 类 101

添加 ZIP 文件 102

为数据库启用 Java 98

Sybase Java 运行时类关于 94

sybase.sql 包运行时类 94

sybase.sql.ASA 包JDBC 2.0 功能 143

System Management Server部署 421

this数据库方法中的 Java 122

TIMESTAMP 数据类型转换 390

try 块Java 70

UnicodeODBC 279

Windows CE 279

UNIXODBC 280, 281

ODBC 应用程序 282

部署问题 412

多线程应用程序 413

目录结构 412

unixodbc.h关于 278

UPDATE 语句set 方法 112

定位 23

数据库中的 Java 111

URLjConnect 148

数据库 149

VARCHAR 数据类型嵌入式 SQL 197

Page 491: Adaptive Server Anywhere

索引索引索引索引

Visual C++支持 180

VMJava 虚拟机 56

启动 137

停止 137

void数据库方法中的 Java 122

数据库中的 Java 方法 64

Watcom C/C++支持 180

Windows服务 284

Windows CEdbtool8.dll 310

ODBC 279, 280

OLE DB 372

不支持数据库中的 Java 57

支持的版本 372

Windows 服务示例代码 190

WITH HOLD 子句游标 21

zip 文件Java 68

A安全

数据库中的 Java 125, 126

安装将 JAR 文件安装到数据库中 102

将 Java 类安装到数据库中 100, 101

静默 418

安装程序部署 411

静默安装 418

B版本

JDBC 71

JDK 71

类 128

数据库中的 Java 71

版本号文件名 413

绑定变量关于 220

包Java 68

jConnect 147

安装 102

数据库中的 Java 77

保存点游标 49

保留字数据库中的 SQL 和 Java 77

备份DBBackup DBTools 函数 320

DBTools 示例 316

嵌入式 SQL 函数 245

编译和链接过程 179编译器

支持的 180

标识符需要引号 268

标准SQLJ 52

标准输出数据库中的 Java 75

不敏感游标更新示例 32

关于 25, 35

简介 30

嵌入式 SQL 27

删除示例 30

477

Page 492: Adaptive Server Anywhere

索引索引索引索引

不支持的 Java 类关于 71

部署CD-ROM 上的数据库 435

dbconsole 实用程序 433

InstallShield 416

Interactive SQL 433

jConnect 431

JDBC 客户端 431

JDBC-ODBC Bridge 431

MobiLink 同步服务器 418

ODBC 423

ODBC 驱动程序 424

ODBC 设置 424, 426

OLE DB 提供程序 422

Open Client 432

SQL Remote 438

Sybase Central 433

System Management Server 421

概述 410

个人数据库服务器 437

关于 409

管理工具 433

静默安装 418

模型 410

嵌入式 SQL 429

嵌入式数据库 437

数据库 435

数据库服务器 434

数据库中的 Java 434

文件位置 412

写文件 415

应用程序 422

应用程序和数据库 409

只读数据库 435

注册表设置 424, 426

478

C操作系统

文件名 413

查询ADO Recordset 对象 377, 378

JDBC 165

单行 210

数据库中的 Java 114

长度 SQLDA 字段关于 227, 229

成员资格结果集 29

程序结构嵌入式 SQL 183

持久性数据库中的 Java 类 76

磁盘空间数据库值中的 Java 127

存储数据库对象中的 Java 127

存储过程INOUT 参数和 Java 124

OUT 参数和 Java 124

结果集 242

嵌入式 SQL 241

数据库中的 Java 122

在嵌入式 SQL 中创建 241

在嵌入式 SQL 中执行 241

错误SQLCODE 204

sqlcode SQLCA 字段 204

代码 204

错误处理Java 69

ODBC 306

错误消息嵌入式 SQL 函数 269

Page 493: Adaptive Server Anywhere

索引索引索引索引

D导入库

DBTools 311

NetWare 185

ODBC 278

Windows CE ODBC 280

简介 179

嵌入式 SQL 181

替代方法 183

导入语句jConnect 147

等同性数据库对象中的 Java 116

点运算符Java 和 SQL 72, 73

定位更新关于 20

定位更新操作 23定位删除操作 23动态 SQL

SQLDA 225

关于 220

动态游标ODBC 27

关于 36

示例 189

读取ODBC 300

嵌入式 SQL 210

限制 20

读取操作多行 22

可滚动游标 22

游标 21

堆大小数据库中的 Java 137

对象插入 168

查询 170

存储格式 104

复制 128

检索 168

类版本 128

类型 63

数据库中 Java 的存储 127

数据库中的 Java 63

卸载和重装 128

对值敏感的游标更新示例 32

关于 38

简介 30

删除示例 30

多个结果集DESCRIBE 语句 244

ODBC 304

多线程应用程序ODBC 276, 293

UNIX 280

嵌入式 SQL 207

数据库中的 Java 121

多行插入 214多行查询

游标 211

多行读取 214多行放置 214

F反馈

提供 xiii

文档 xiii

返回代码 313ODBC 306

范围Java 68

方法

479

Page 494: Adaptive Server Anywhere

索引索引索引索引

>> 73

private 68

protected 68

public 68

void 返回类型 122

点运算符 72

静态 65

类 65

声明 66

实例 65

数据库中的 Java 64

访问修改者Java 68

非链接模式控制 46

实现 47

事务 46

分布式事务EAServer 406

关于 397, 398, 404

恢复 405

三层计算 400

体系结构 400, 402

征用 400

分布式事务处理协调器三层计算 401

分布式应用程序关于 170

示例 172

要求 170

服务示例代码 190, 284

服务器定位 266

服务器地址嵌入式 SQL 函数 257

服务器端自动提交关于 47

480

复制数据库对象中的 Java 128

G高速缓存

数据库中的 Java 136

格式数据库对象中的 Java 127

隔离级别应用程序 48

游标 21

游标敏感性和 43

个人服务器部署 437

更新游标 379

工作表游标性能 41

功能支持 396

公共字段问题 78

构造函数Java 69

插入数据 109

关于 64

关键字数据库中的 SQL 和 Java 77

过程ODBC 304

结果集 242

嵌入式 SQL 241

H函数

DBTools 320

Page 495: Adaptive Server Anywhere

索引索引索引索引

调用 DBTools 函数 312

嵌入式 SQL 251

宏_SQL_OS_NETWARE 184

_SQL_OS_UNIX 184

_SQL_OS_WINNT 184

后台处理回调函数 245

环境句柄ODBC 286

恢复分布式事务 405

回调DB_CALLBACK_CONN_DROPPED 260

DB_CALLBACK_DEBUG_MESSAGE 260

DB_CALLBACK_FINISH 260

DB_CALLBACK_MESSAGE 261

DB_CALLBACK_START 260

DB_CALLBACK_WAIT 260

回调函数嵌入式 SQL 245

注册 259

混合游标ODBC 27

活动连接 260

J集合函数

数据库列中的 Java 117

技术支持新闻组 xiii

计算列INSERT 语句 134

UPDATE 语句 134

触发器 134

创建 133

数据库中的 Java 133

限制 135

重新计算 135

加密DBTools 接口 324

检索ODBC 300

SQLDA 和 232

对象 170

键集驱动的游标ODBC 27

关于 38

接口Java 69

接口库动态装载 183

关于 178

文件名 178

截断FETCH 语句 202

在 FETCH 上 201

指示符变量 202

结构压缩头文件 181

结果集ADO Recordset 对象 377, 378

ODBC 299, 304

Open Client 394

存储过程 242

多个 ODBC 304

检索 ODBC 300

使用 20

数据库存储过程中的 Java 122

数据库方法中的 Java 122

游标 15

元数据 44

静态 SQL关于 220

481

Page 496: Adaptive Server Anywhere

索引索引索引索引

静态方法关于 65

静态游标ODBC 27

关于 35

句柄分配 ODBC 287

关于 ODBC 286

K可滚动游标 22

JDBC 支持 141

可见的更改游标 29

可重定位已定义 136

客户端自动提交关于 47

空白填补嵌入式 SQL 中的字符串 192

空白填充枚举 366空值

数据库中的 Java 106

库嵌入式 SQL 181

库函数嵌入式 SQL 251

块状游标 22ODBC 28

宽插入 214宽读取 22

关于 214

宽放置 214捆绑参数

准备好的语句 13

482

L类

Java 67

安装 100

版本 103

编译 62

创建 100

导入 172

更新 103

构造函数 64

关于 62

实例 67

示例 108

运行时 71

支持的 58

作为数据类型 106

类方法关于 65

类型对象 63

类字段关于 65

例外Java 69

联机备份嵌入式 SQL 245

连接ADO Connection 对象 374

jConnect 149

jConnect URL 148

JDBC 145, 153

JDBC 客户端应用程序 153

JDBC 缺省值 159

JDBC 示例 153, 157

ODBC 编程 291

ODBC 函数 290

ODBC 属性 292

Page 497: Adaptive Server Anywhere

索引索引索引索引

服务器中的 JDBC 157

函数 265

连接句柄ODBC 286

链接模式控制 46

实现 47

事务 46

两阶段提交和 Open Client 396

三层计算 400

列数据库数据类型中的 Java 106

数据库中更新 Java 111

M枚举

DBTools 接口 366

面向对象的编程风格 78

数据库中的 Java 67

描述结果集 44

描述符描述结果集 44

敏感性隔离级别和 43

更新示例 32

删除示例 30

游标 29, 30

敏感性未定型游标更新示例 32

关于 37

简介 30

删除示例 30

敏感游标更新示例 32

关于 36

简介 30

嵌入式 SQL 27

删除示例 30

名称 SQLDA 字段关于 227

命令ADO Command 对象 376

命令行实用程序部署 438

命名空间数据库中的 Java 137

目录结构UNIX 412

N内存

数据库中的 Java 136

P排序

数据库对象中的 Java 116

胖游标 22平台

游标 25

支持数据库中的 Java 57

Q启动

使用 jConnect 的数据库 149

嵌入式 SQLSQL 语句 10

编译和链接过程 179

导入库 181

483

Page 498: Adaptive Server Anywhere

索引索引索引索引

动态游标 189

动态语句 220

读取数据 210

关于 177

函数 251

简介 4静态语句 220

开发 178

命令汇总 270

示例程序 182

授权 248

头文件 181

行号 248

游标 27, 186, 211

游标类型 25

主机变量 196

自动提交模式 46

字符串 249

嵌入式数据库部署 437

请求中止 255

请求处理嵌入式 SQL 245

区分大小写数据库数据类型中的 Java 106

数据库中的 Java 和 SQL 74

取消请求嵌入式 SQL 245

权限JDBC 169

缺省数据库中的 Java 106

R入口点

484

调用 DBTools 函数 312

软件返回代码 313

S三层计算

EAServer 401

Microsoft Transaction Server 401

分布式事务 400

分布式事务处理协调器 401

关于 397

体系结构 399

资源分发器 400

资源管理器 400

删除JAR 文件 113

Java 类 113

设置使用 SQLDA 的值 231

声明嵌入式 SQL 数据类型 192

主机变量 196

声明部分关于 196

升级数据库向导为数据库启用 Java 98

实例Java 类 67

实例方法关于 65

实例化定义 67

实例字段关于 65

实体数据库中的 Java 130

实用程序

Page 499: Adaptive Server Anywhere

索引索引索引索引

SQL 预处理器 247

部署数据库实用程序 438

示例DBTools 程序 316

esqldll.c 184

ODBC 283

Windows 服务 284

嵌入式 SQL 187

嵌入式 SQL 应用程序 186

嵌入式 SQL 中的静态游标 189

示例数据库关于 asademo.db xii

数据库中的 Java 90

事务ODBC 288

分布式 398, 404

隔离级别 48

应用程序开发 46

游标 48

自动提交模式 46

事务处理协调器EAServer 406

事务属性组件 407

手动提交模式控制 46

实现 47

事务 46

书签 28ODBC 游标 303

属性db_get_property 函数 257

数据库中的 Java 130

数据库URL 149

部署 435

启用 Java 94, 96, 98

数据库中的 Java 130

数据库服务器部署 434

函数 265

数据库工具接口a_backup_db 结构 334

a_change_log 结构 336

a_compress_db 结构 338

a_compress_stats 结构 339

a_create_db 结构 340

a_crypt_db 结构 342

a_db_collation 结构 343

a_db_info 结构 345

a_dblic_info 结构 347

a_dbtools_info 结构 348

a_name 结构 351

a_stats_line 结构 352

a_sync_db 结构 352

a_syncpub 结构 354

a_sysinfo 结构 355

a_table_info 结构 356

a_translate_log 结构 357

a_truncate_log 结构 358

a_validate_db 结构 362

a_validate_type 枚举 368

a_writefile 结构 364

an_erase_db 结构 349

an_expand_db 结构 350

an_unload_db 结构 359

an_upgrade_db 结构 361

DBBackup 函数 320

DBChangeLogName 函数 320

DBChangeWriteFile 函数 321

DBCollate 函数 321

DBCompress 函数 322

DBCreate 函数 322

DBCreateWriteFile 函数 323

DBCrypt 函数 324

485

Page 500: Adaptive Server Anywhere

索引索引索引索引

DBErase 函数 324

DBExpand 函数 325

DBInfo 函数 325

DBInfoDump 函数 326

DBInfoFree 函数 326

DBLicense 函数 327

DBStatusWriteFile 函数 328

DBToolsFini 函数 329

DBToolsInit 函数 329

DBToolsVersion 函数 330

dbtran_userlist_type 枚举 367

DBTranslateLog 函数 331

DBTruncateLog 函数 331

DBUnload 函数 332

dbunload 类型枚举 367

DBUpgrade 函数 332

DBValidate 函数 333

dbxtract 332

关于 309

空白填充枚举 366

详细枚举 366

数据库设计数据库中的 Java 130

数据库属性db_get_property 函数 257

数据库选项用于 jConnect 的集 150

数据库值中的 Java性能 127

数据库中的 JavaAPI 58, 71

compareTo 方法 117

main 方法 75, 120

安全管理 125

安装类 100

版本 71

比较对象 116

486

编译类 62

部署 434

插入 109

插入对象 111

查询 114

持久性 76

创建列 106

存储 127

堆大小 137

对象 63

方法 64

复制对象 128

概述 90

更新列 112

更新值 111

计算列 133

简介 52, 62

教程 80

空值 106

类版本 128

命名空间 137

内存问题 136

启用数据库 94, 96, 98

缺省 106

删除类 113

删除行 113

使用文档 53

示例表 90

数据库设计 130

数据类型 106

索引 117, 127

未找到过程错误 122

问答 55

卸载和重装对象 128

虚拟机 55, 56, 137

运行时环境 71, 92

Page 501: Adaptive Server Anywhere

索引索引索引索引

运行时类 94

支持的类 58

支持的平台 57

主键 117

主要功能 55

转义字符 76

字段 64

数据类型C 数据类型 197

Open Client 389

SQLDA 227

动态 SQL 225

范围 390

嵌入式 SQL 192

数据库中的 Java 106

映射 389

主机变量 197

数据类型转换指示符变量 202

数组读取关于 214

索引数据库中的 Java 117, 127, 133

T提交

来自 ODBC 的事务 288

添加JAR 文件 102

数据库中的 Java 类 101

头文件ODBC 278

嵌入式 SQL 181

图标手册中使用的 x

W唯一列

数据库列中的 Java 117

唯一游标关于 25

未找到过程错误Java 方法 164

位字段使用 316

文档SQL Anywhere Studio vii

约定 ix文件

部署位置 412

命名约定 413

文件名版本号 413

语言 413

约定 413

X析构函数

Java 69

线程ODBC 276

ODBC 应用程序 293

UNIX 开发 280

嵌入式 SQL 207

数据库中的 Java 121

线程应用程序UNIX 413

详细枚举数据库工具接口 366

响应文件定义 418

向导JAR 和 ZIP 文件创建 102

487

Page 502: Adaptive Server Anywhere

索引索引索引索引

Java 类创建 81, 101, 158

升级数据库向导 98

消息服务器 261

回调 261

写文件部署 415

新闻组技术支持 xiii

行长度SQL 预处理器输出 248

行号SQL 预处理器 248

性能JDBC 166

JDBC 驱动程序 141

prepared 语句 296

数据库值中的 Java 127

游标 41, 42

准备好的语句 12

序列化表中的对象 104

对象 171

分布式计算 172

数据库对象中的 Java 127

Y要求

Open Client 应用程序 388

疑难解答数据库方法中的 Java 122

游标定位 20

以空值终止的字符串嵌入式 SQL 数据类型 192

溢出错误数据类型转换 390

引号

488

数据库中的 Java 字符串 74

应用程序SQL 10

部署 409, 422

部署嵌入式 SQL 429

用户定义的类数据库中的 Java 72

用引号引起的标识符SQL_needs_quotes 函数 268

游标 20, 28ADO 27

DYNAMIC SCROLL 25, 37

NO SCROLL 25, 35

ODBC 27, 299

ODBC 更新 302

ODBC 结果集 300

ODBC 删除 302

ODBC 书签 303

OLE DB 27

Open Client 393

SCROLL 25, 38

保存点 49

不敏感 25, 35

成员资格 29

存储过程 242

定位 20

动态 36

读取多行 22

读取行 20, 21

对值敏感的 38

分步骤 17

隔离级别 21

更新 379, 394

更新和删除 23

工作表 41

关于 15

简介 15

Page 503: Adaptive Server Anywhere

索引索引索引索引

键集驱动的 38

结果集 15

静态 35

可滚动 22

可见的更改 29

可用性 25

描述 44

敏感 36

敏感性 29, 30

敏感性示例 30, 32

敏感性未定 37

内部 29

胖 22

平台 25

嵌入式 SQL 27, 211

请求 26

取消 24, 255

删除 394

使用 15, 20

示例 C 代码 186

事务 48

顺序 29

唯一 25

未指定敏感性 37

性能 41, 42

选择 ODBC 游标特性 299

值 29

只读 25

准备好的语句 19

游标定位疑难解答 20

语句COMMIT 48

DELETE 定位 23

insert 12

PUT 23

ROLLBACK 48

ROLLBACK TO SAVEPOINT 49

UPDATE 定位 23

语句句柄ODBC 286

语言文件名 413

语言 DLL获取 414

预处理器关于 178

运行 180

预读读取多行 22

游标 42

游标性能 41

约定文档 ix文件名 413

运行时环境数据库中的 Java 92

运行时类安装 94

内容 94

数据库中的 Java 71

Z在数据库中使用 Java 89占位符

动态 SQL 220

征用分布式事务 400

支持新闻组 xiii

支持的平台OLE DB 372

指示符变量NULL 201

489

Page 504: Adaptive Server Anywhere

索引索引索引索引

SQLDA 227

关于 200

截断 202

数据类型转换 202

值的汇总 202

只读部署数据库 435

只读游标关于 25

主机变量SQLDA 227

关于 196

声明 196

数据类型 197

用法 199

主键数据库列中的 Java 117

注册表ODBC 427

部署 424, 426

转换数据类型 202

转义字符SQL 76

数据库中的 Java 76

准备提交 400

准备好的语句捆绑参数 13

删除 13

使用 12

游标 19

资源分发器三层计算 400

资源管理器关于 398

三层计算 400

子句

490

WITH HOLD 21

自动提交JDBC 159

ODBC 288

控制 46

实现 47

事务 46

字段private 68

protected 68

public 68

公共 78

类 65

实例 65

数据库中的 Java 64

字符串 249DT_STRING 的空白填补 192

数据库中的 Java 74

数据类型 269

字符集转换JDBC-ODBC Bridge 152

字节代码Java 类 56

组件事务属性 407